UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,312 lines (1,071 loc) 107 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1219); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1015: /***/ (function(module, exports) { module.exports = require("./kendo.data"); /***/ }), /***/ 1038: /***/ (function(module, exports) { module.exports = require("./kendo.popup"); /***/ }), /***/ 1219: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1038), __webpack_require__(1015) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); })(function(){ var __meta__ = { // jshint ignore:line id: "menu", name: "Menu", category: "web", description: "The Menu widget displays hierarchical data as a multi-level menu.", depends: [ "popup", "data", "data.odata" ] }; (function ($, undefined) { var kendo = window.kendo, ui = kendo.ui, activeElement = kendo._activeElement, touch = (kendo.support.touch && kendo.support.mobileOS), isArray = $.isArray, HierarchicalDataSource = kendo.data.HierarchicalDataSource, MOUSEDOWN = "mousedown", CLICK = "click", DELAY = 30, SCROLLSPEED = 50, extend = $.extend, proxy = $.proxy, each = $.each, template = kendo.template, keys = kendo.keys, Widget = ui.Widget, excludedNodesRegExp = /^(ul|a|div)$/i, NS = ".kendoMenu", IMG = "img", OPEN = "open", MENU = "k-menu", LINK = "k-link k-menu-link", LINK_SELECTOR = ".k-link", ICON_SELECTOR = ".k-icon", LAST = "k-last", CLOSE = "close", TIMER = "timer", FIRST = "k-first", IMAGE = "k-image", SELECT = "select", ZINDEX = "zIndex", ACTIVATE = "activate", DEACTIVATE = "deactivate", POINTERDOWN = "touchstart" + NS + " MSPointerDown" + NS + " pointerdown" + NS, pointers = kendo.support.pointers, msPointers = kendo.support.msPointers, allPointers = msPointers || pointers, CHANGE = "change", ERROR = "error", TOUCHSTART = kendo.support.touch ? "touchstart" : "", MOUSEENTER = pointers ? "pointerover" : (msPointers ? "MSPointerOver" : "mouseenter"), MOUSELEAVE = pointers ? "pointerout" : (msPointers ? "MSPointerOut" : "mouseleave"), MOUSEWHEEL = "DOMMouseScroll" + NS + " mousewheel" + NS, RESIZE = kendo.support.resize + NS, SCROLLWIDTH = "scrollWidth", SCROLLHEIGHT = "scrollHeight", OFFSETWIDTH = "offsetWidth", OFFSETHEIGHT = "offsetHeight", POPUP_ID_ATTR = "group", POPUP_OPENER_ATTR = "groupparent", DOCUMENT_ELEMENT = $(document.documentElement), KENDOPOPUP = "kendoPopup", DEFAULTSTATE = "k-state-default", HOVERSTATE = "k-state-hover", FOCUSEDSTATE = "k-state-focused", DISABLEDSTATE = "k-state-disabled", SELECTEDSTATE = "k-state-selected", menuSelector = ".k-menu", groupSelector = ".k-menu-group", animationContainerSelector = ".k-animation-container", popupSelector = groupSelector + "," + animationContainerSelector, allItemsSelector = ":not(.k-list) > .k-item", disabledSelector = ".k-item.k-state-disabled", itemSelector = ".k-item", availableItemsSelector = ".k-item:not(.k-state-disabled)", linkSelector = ".k-item:not(.k-state-disabled) > .k-link", exclusionSelector = ":not(.k-item.k-separator)", nextSelector = itemSelector + exclusionSelector + ":eq(0)", lastSelector = itemSelector + exclusionSelector + ":last", templateSelector = "div:not(.k-animation-container,.k-list-container)", scrollButtonSelector = ".k-menu-scroll-button", touchPointerTypes = { "2": 1, "touch": 1 }, STRING = "string", DATABOUND = "dataBound", bindings = { text: "dataTextField", url: "dataUrlField", spriteCssClass: "dataSpriteCssClassField", imageUrl: "dataImageUrlField", imageAttr: "dataImageAttrField", content: "dataContentField" }, rendering = { wrapperCssClass: function (group, item) { var result = "k-item", index = item.index; if (item.enabled === false) { result += " k-state-disabled"; } else { result += " k-state-default"; } if (group.firstLevel && index === 0) { result += " k-first"; } if (index == group.length-1) { result += " k-last"; } if (item.cssClass) { result += " " + item.cssClass; } if(item.attr && item.attr.hasOwnProperty("class")) { result += " " + item.attr["class"]; } if(item.selected) { result += " " + SELECTEDSTATE; } return result; }, itemCssAttributes: function (item) { var result = ""; var attributes = item.attr || {}; for (var attr in attributes) { if(attributes.hasOwnProperty(attr) && attr !== "class") { result += attr + "=\"" + attributes[attr] + "\" "; } } return result; }, imageCssAttributes: function (imgAttributes) { var result = ""; var attributes = imgAttributes && imgAttributes.toJSON ? imgAttributes.toJSON() : {}; if (!attributes['class']) { attributes['class'] = IMAGE; } else { attributes['class'] += " " + IMAGE; } for (var attr in attributes) { if(attributes.hasOwnProperty(attr)) { result += attr + "=\"" + attributes[attr] + "\" "; } } return result; }, contentCssAttributes: function (item) { var result = ""; var attributes = item.contentAttr || {}; var defaultClasses = "k-content k-group k-menu-group"; if (!attributes['class']) { attributes['class'] = defaultClasses; } else { attributes['class'] += " " + defaultClasses; } for (var attr in attributes) { if(attributes.hasOwnProperty(attr)) { result += attr + "=\"" + attributes[attr] + "\" "; } } return result; }, textClass: function() { return LINK; }, arrowClass: function(item, group) { var result = "k-icon"; if (group.horizontal) { result += " k-i-arrow-60-down"; } else { result += " k-i-arrow-60-right"; } return result; }, groupAttributes: function(group) { return group.expanded !== true ? " style='display:none'" : ""; }, groupCssClass: function() { return "k-group k-menu-group"; }, content: function(item) { return item.content ? item.content : "&nbsp;"; } }; function getEffectDirection(direction, root) { direction = direction.split(" ")[!root+0] || direction; return direction.replace("top", "up").replace("bottom", "down"); } function parseDirection(direction, root, isRtl) { direction = direction.split(" ")[!root+0] || direction; var output = { origin: ["bottom", (isRtl ? "right" : "left")], position: ["top", (isRtl ? "right" : "left")] }, horizontal = /left|right/.test(direction); if (horizontal) { output.origin = [ "top", direction ]; output.position[1] = kendo.directions[direction].reverse; } else { output.origin[0] = direction; output.position[0] = kendo.directions[direction].reverse; } output.origin = output.origin.join(" "); output.position = output.position.join(" "); return output; } function contains(parent, child) { try { return $.contains(parent, child); } catch (e) { return false; } } function updateItemClasses (item) { item = $(item); item.addClass("k-item") .children(IMG) .addClass(IMAGE); item .children("a") .addClass(LINK) .children(IMG) .addClass(IMAGE); item .filter(":not([disabled])") .addClass(DEFAULTSTATE); item .filter(".k-separator") .empty() .append("&nbsp;"); item .filter("li[disabled]") .addClass(DISABLEDSTATE) .removeAttr("disabled") .attr("aria-disabled", true); if (!item.filter("[role]").length) { item.attr("role", "menuitem"); } if (!item.children(LINK_SELECTOR).length) { item .contents() // exclude groups, real links, templates and empty text nodes .filter(function() { return (!this.nodeName.match(excludedNodesRegExp) && !(this.nodeType == 3 && !$.trim(this.nodeValue))); }) .wrapAll("<span class='" + LINK + "'/>"); } updateArrow(item); updateFirstLast(item); } function updateArrow (item) { item = $(item); item.find("> .k-link > [class*=k-i-arrow-60]:not(.k-sprite)").remove(); item.filter(":has(.k-menu-group)") .children(".k-link:not(:has([class*=k-i-arrow]:not(.k-sprite)))") .each(function () { var item = $(this), arrowCssClass = getArrowCssClass(item); item.append("<span class='k-icon" + arrowCssClass + " k-menu-expand-arrow'/>"); }); } function getArrowCssClass (item) { var arrowCssClass, parent = item.parent().parent(), isRtl = kendo.support.isRtl(parent); if (parent.hasClass(MENU + "-horizontal")) { arrowCssClass = " k-i-arrow-60-down"; } else { if (isRtl) { arrowCssClass = " k-i-arrow-60-left"; } else { arrowCssClass = " k-i-arrow-60-right"; } } return arrowCssClass; } function updateFirstLast (item) { item = $(item); item.filter(".k-first:not(:first-child)").removeClass(FIRST); item.filter(".k-last:not(:last-child)").removeClass(LAST); item.filter(":first-child").addClass(FIRST); item.filter(":last-child").addClass(LAST); } function updateHasAriaPopup (parents) { if (parents && parents.length) { for (var index in parents) { var parentLi = parents.eq(index); if (parentLi.find("ul").length) { parentLi.attr("aria-haspopup", true); } else { parentLi.removeAttr("aria-haspopup"); } } } } function getParentLiItems(group) { if (!group.hasClass(MENU)) { return group.parentsUntil("." + MENU, "li"); } } function storeItemSelectEventHandler (element, options) { var selectHandler = getItemSelectEventHandler(options); if(selectHandler) { setItemData(element, selectHandler); } if (options.items) { $(element).children("ul").children("li").each(function(i){ storeItemSelectEventHandler(this, options.items[i]); }); } } function setItemData (element, selectHandler) { $(element).children(".k-link").data({ selectHandler : selectHandler }); } function getItemSelectEventHandler (options) { var selectHandler = options.select, isFunction = kendo.isFunction; if (selectHandler && isFunction(selectHandler)) { return selectHandler; } return null; } function popupOpenerSelector(id){ return id ? "li[data-groupparent='" + id + "']" : "li[data-groupparent]"; } function popupGroupSelector(id) { return id ? "ul[data-group='" + id + "']" : "ul[data-group]"; } function getChildPopups (currentPopup, overflowWrapper) { var childPopupOpener = currentPopup.find(popupOpenerSelector()); var result = []; childPopupOpener.each(function(i, opener){ opener = $(opener); var popupId = opener.data(POPUP_OPENER_ATTR); var popup = currentPopup; while(popupId) { popup = overflowWrapper.find(popupGroupSelector(popupId) + ":visible"); if (popup.length) { result.push(popup); } opener = popup.find(popupOpenerSelector()); popupId = opener.data(POPUP_OPENER_ATTR); } }); return result; } function popupParentItem(popupElement, overflowWrapper) { var popupId = popupElement.data(POPUP_ID_ATTR); return popupId ? overflowWrapper.find(popupOpenerSelector(popupId)) : $([]); } function itemPopup(item, overflowWrapper) { var popupId = item.data(POPUP_OPENER_ATTR); return popupId ? overflowWrapper.children(animationContainerSelector).children(popupGroupSelector(popupId)) : $([]); } function overflowMenuParents(current, overflowWrapper) { var parents = []; var getParents = function(item){ while (item.parentNode && !overflowWrapper.is(item.parentNode)) { parents.push(item.parentNode); item = item.parentNode; } }; var elem = current[0] || current; getParents(elem); var last = parents[parents.length - 1]; while($(last).is(animationContainerSelector)){ var popupElement = $(last).children("ul"); elem = popupParentItem(popupElement, overflowWrapper)[0]; if (!elem) { break; } parents.push(elem); getParents(elem); last = parents[parents.length - 1]; } return parents; } function mousewheelDelta(e) { var delta = 0; if (e.wheelDelta) { delta = -e.wheelDelta / 120; delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta); } if (e.detail) { delta = Math.round(e.detail / 3); } return delta; } function parentsScroll(current, scrollDirection) { var scroll = 0; var parent = current.parentNode; while(parent && !isNaN(parent[scrollDirection])) { scroll += parent[scrollDirection]; parent = parent.parentNode; } return scroll; } function isPointerTouch(e){ return allPointers && e.originalEvent && e.originalEvent.pointerType in touchPointerTypes; } function isTouch(e){ var ev = e.originalEvent; return touch && /touch/i.test(ev.type || ""); } function removeSpacesBetweenItems(ul){ ul.contents().filter(function(){ return this.nodeName != "LI"; }).remove(); } var Menu = kendo.ui.DataBoundWidget.extend({ init: function(element, options) { var that = this; Widget.fn.init.call(that, element, options); element = that.wrapper = that.element; options = that.options; that._accessors(); that._templates(); that._dataSource(); that._updateClasses(); that._animations(options); that.nextItemZIndex = 100; that._tabindex(); that._initOverflow(options); that._attachMenuEventsHandlers(); if (options.openOnClick) { that.clicked = false; } element.attr("role", "menubar"); if (element[0].id) { that._ariaId = kendo.format("{0}_mn_active", element[0].id); } kendo.notify(that); }, events: [ OPEN, CLOSE, ACTIVATE, DEACTIVATE, SELECT, DATABOUND ], options: { name: "Menu", animation: { open: { duration: 200 }, close: { // if close animation effects are defined, they will be used instead of open.reverse duration: 100 } }, orientation: "horizontal", direction: "default", openOnClick: false, closeOnClick: true, hoverDelay: 100, scrollable: false, popupCollision: undefined }, _initData: function() { var that = this; if (that.dataSource) { that.angular("cleanup", function(){ return { elements: that.element.children() }; }); that.element.empty(); that.append(that.dataSource.view(), that.element); that.angular("compile", function(){ return { elements: that.element.children() }; }); } }, _attachMenuEventsHandlers: function() { var that = this; var element = that.element; var options = that.options; var overflowWrapper = that._overflowWrapper(); (overflowWrapper || element).on(POINTERDOWN, itemSelector, proxy(that._focusHandler, that)) .on(CLICK + NS, disabledSelector, false) .on(CLICK + NS, itemSelector, proxy(that._click , that)) .on(POINTERDOWN + " " + MOUSEDOWN + NS, ".k-content", proxy(that._preventClose, that)) .on(MOUSEENTER + NS, availableItemsSelector, proxy(that._mouseenter, that)) .on(MOUSELEAVE + NS, availableItemsSelector, proxy(that._mouseleave, that)) .on(MOUSEDOWN + NS, availableItemsSelector, proxy(that._mousedown, that)) .on(TOUCHSTART + NS + " " + MOUSEENTER + NS + " " + MOUSELEAVE + NS + " " + MOUSEDOWN + NS + " " + CLICK + NS, linkSelector, proxy(that._toggleHover, that)); element.on("keydown" + NS, proxy(that._keydown, that)) .on("focus" + NS, proxy(that._focus, that)) .on("focus" + NS, ".k-content", proxy(that._focus, that)) .on("blur" + NS, proxy(that._removeHoverItem, that)) .on("blur" + NS, "[tabindex]", proxy(that._checkActiveElement, that)); if (overflowWrapper) { overflowWrapper .on(MOUSELEAVE + NS, popupSelector, proxy(that._mouseleavePopup, that)) .on(MOUSEENTER + NS, popupSelector, proxy(that._mouseenterPopup, that)); } if (options.openOnClick) { that._documentClickHandler = proxy(that._documentClick, that); $(document).click(that._documentClickHandler); } }, _detachMenuEventsHandlers: function() { var that = this; var overflowWrapper = that._overflowWrapper(); if (overflowWrapper) { overflowWrapper.off(NS); } that.element.off(NS); if (that._documentClickHandler) { $(document).unbind("click", that._documentClickHandler); } }, _initOverflow: function(options) { var that = this; var isHorizontal = options.orientation == "horizontal"; var backwardBtn, forwardBtn; if (options.scrollable) { that._openedPopups = {}; that._scrollWrapper = that.element.wrap("<div class='k-menu-scroll-wrapper " + options.orientation + "'></div>").parent(); if (isHorizontal) { removeSpacesBetweenItems(that.element); } backwardBtn = $(that.templates.scrollButton({direction: isHorizontal ? "left" : "up"})); forwardBtn = $(that.templates.scrollButton({direction: isHorizontal ? "right": "down"})); backwardBtn.add(forwardBtn).appendTo(that._scrollWrapper); that._initScrolling(that.element, backwardBtn, forwardBtn, isHorizontal); var initialWidth = that.element.outerWidth(); var initialCssWidth = that.element[0].style.width; initialCssWidth = initialCssWidth === "auto" ? "" : initialCssWidth; if (isHorizontal) { $(window).on(RESIZE, kendo.throttle(function(){ that._setOverflowWrapperWidth(initialWidth, initialCssWidth); that._toggleScrollButtons(that.element, backwardBtn, forwardBtn, isHorizontal); }, 100)); } that._setOverflowWrapperWidth(initialWidth, initialCssWidth); that._toggleScrollButtons(that.element, backwardBtn, forwardBtn, isHorizontal); } }, _overflowWrapper: function(){ return this._scrollWrapper || this._popupsWrapper; }, _setOverflowWrapperWidth: function(initialWidth, initialCssWidth) { var that = this; var wrapperCssWidth = that._scrollWrapper.css("width"); that._scrollWrapper.css({width: ""}); var wrapperWidth = that._scrollWrapper.outerWidth(); that._scrollWrapper.css({ width: wrapperCssWidth }); var menuWidth = that.element.outerWidth(); var borders = that.element[0].offsetWidth - that.element[0].clientWidth; if (menuWidth != wrapperWidth && wrapperWidth > 0) { var width = initialCssWidth ? Math.min(initialWidth, wrapperWidth) : wrapperWidth; that.element.width(width - borders); that._scrollWrapper.width(width); } }, _reinitOverflow: function(options) { var that = this; var overflowChanged = ((options.scrollable && !that.options.scrollable) || (!options.scrollable && that.options.scrollable)) || (options.scrollable && that.options.scrollable && options.scrollable.distance != that.options.scrollable.distance) || options.orientation != that.options.orientation; if (overflowChanged) { that._detachMenuEventsHandlers(); that._destroyOverflow(); that._initOverflow(options); that._attachMenuEventsHandlers(); } }, _destroyOverflow: function() { var that = this; var overflowWrapper = that._overflowWrapper(); if(overflowWrapper) { overflowWrapper.off(NS); overflowWrapper.find(scrollButtonSelector).off(NS).remove(); overflowWrapper.children(animationContainerSelector).each(function(i, popupWrapper){ var ul = $(popupWrapper).children(groupSelector); ul.off(MOUSEWHEEL); var popupParentLi = popupParentItem(ul, overflowWrapper); if (popupParentLi.length) { popupParentLi.append(popupWrapper); } }); overflowWrapper.find(popupOpenerSelector()).removeAttr("data-groupparent"); overflowWrapper.find(popupGroupSelector()).removeAttr("data-group"); that.element.off(MOUSEWHEEL); $(window).off(RESIZE); overflowWrapper.contents().unwrap(); that._scrollWrapper = that._popupsWrapper = that._openedPopups = undefined; } }, _initScrolling: function(scrollElement, backwardBtn, forwardBtn, isHorizontal) { var that = this; var scrollable = that.options.scrollable; var distance = $.isNumeric(scrollable.distance) ? scrollable.distance : SCROLLSPEED; var mouseWheelDistance = distance / 2; var backward = "-=" + distance; var forward = "+=" + distance; var backwardDouble = "-=" + distance * 2; var forwardDouble = "+=" + distance * 2; var scrolling = false; var touchEvents = false; var scroll = function(value) { var scrollValue = isHorizontal ? {"scrollLeft": value} : { "scrollTop": value }; scrollElement.finish().animate(scrollValue, "fast", "linear", function () { if (scrolling) { scroll(value); } }); that._toggleScrollButtons(scrollElement, backwardBtn, forwardBtn, isHorizontal); }; var mouseenterHandler = function(e) { if (!scrolling && !touchEvents) { scroll(e.data.direction); scrolling = true; } }; var mousedownHandler = function(e) { var scrollValue = isHorizontal ? {"scrollLeft": e.data.direction} : { "scrollTop": e.data.direction }; touchEvents = isTouch(e) || isPointerTouch(e); scrollElement.stop().animate(scrollValue, "fast", "linear", function(){ if (!touchEvents) { $(e.currentTarget).trigger(MOUSEENTER); } else { that._toggleScrollButtons(scrollElement, backwardBtn, forwardBtn, isHorizontal); scrolling = true; } }); scrolling = false; e.stopPropagation(); e.preventDefault(); }; backwardBtn.on(MOUSEENTER + NS, {direction: backward}, mouseenterHandler) .on(kendo.eventMap.down + NS, {direction: backwardDouble}, mousedownHandler); forwardBtn.on(MOUSEENTER + NS, {direction: forward}, mouseenterHandler) .on(kendo.eventMap.down + NS, {direction: forwardDouble}, mousedownHandler); backwardBtn.add(forwardBtn) .on(MOUSELEAVE + NS, function() { scrollElement.stop(); scrolling = false; that._toggleScrollButtons(scrollElement, backwardBtn, forwardBtn, isHorizontal); }); scrollElement.on(MOUSEWHEEL, function(e){ if (!e.ctrlKey && !e.shiftKey && !e.altKey) { var wheelDelta = mousewheelDelta(e.originalEvent); var scrollSpeed = Math.abs(wheelDelta) * mouseWheelDistance; var value = (wheelDelta > 0 ? "+=" : "-=") + scrollSpeed; var scrollValue = isHorizontal ? {"scrollLeft": value} : {"scrollTop": value }; that._closeChildPopups(scrollElement); scrollElement.finish().animate(scrollValue, "fast", "linear", function(){ that._toggleScrollButtons(scrollElement, backwardBtn, forwardBtn, isHorizontal); }); e.preventDefault(); } }); }, _toggleScrollButtons: function(scrollElement, backwardBtn, forwardBtn, horizontal) { var currentScroll = horizontal ? scrollElement.scrollLeft() : scrollElement.scrollTop(); var scrollSize = horizontal ? SCROLLWIDTH : SCROLLHEIGHT; var offset = horizontal ? OFFSETWIDTH : OFFSETHEIGHT; backwardBtn.toggle(currentScroll !== 0); forwardBtn.toggle(currentScroll < scrollElement[0][scrollSize] - scrollElement[0][offset] - 1); }, setOptions: function(options) { var animation = this.options.animation; this._animations(options); options.animation = extend(true, animation, options.animation); if ("dataSource" in options) { this._dataSource(options); } this._updateClasses(); this._reinitOverflow(options); Widget.fn.setOptions.call(this, options); }, destroy: function() { var that = this; Widget.fn.destroy.call(that); that._detachMenuEventsHandlers(); that._destroyOverflow(); kendo.destroy(that.element); }, enable: function (element, enable) { this._toggleDisabled(element, enable !== false); return this; }, disable: function (element) { this._toggleDisabled(element, false); return this; }, attemptGetItem: function (candidate) { candidate = candidate || this.element; var item = this.element.find(candidate); var overflowWrapper = this._overflowWrapper(); if (item.length || candidate === this.element){ return item; } else if (overflowWrapper) { return overflowWrapper.find(candidate); } else { return $(); } }, append: function (item, referenceItem) { referenceItem = this.attemptGetItem(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.length ? referenceItem.find("> .k-menu-group, > .k-animation-container > .k-menu-group") : null); each(inserted.items, function (i) { inserted.group.append(this); updateArrow(this); storeItemSelectEventHandler(this, item[i] || item); }); updateArrow(referenceItem); updateFirstLast(inserted.group.find(".k-first, .k-last").add(inserted.items)); updateHasAriaPopup(getParentLiItems(inserted.group)); return this; }, insertBefore: function (item, referenceItem) { referenceItem = this.attemptGetItem(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function (i) { referenceItem.before(this); updateArrow(this); updateFirstLast(this); storeItemSelectEventHandler(this, item[i] || item); }); updateFirstLast(referenceItem); return this; }, insertAfter: function (item, referenceItem) { referenceItem = this.attemptGetItem(referenceItem); var inserted = this._insert(item, referenceItem, referenceItem.parent()); each(inserted.items, function (i) { referenceItem.after(this); updateArrow(this); updateFirstLast(this); storeItemSelectEventHandler(this, item[i] || item); }); updateFirstLast(referenceItem); return this; }, _insert: function (item, referenceItem, parent) { var that = this, items, groups; if (!referenceItem || !referenceItem.length) { parent = that.element; } var plain = $.isPlainObject(item) || item instanceof kendo.data.ObservableObject, groupData = { firstLevel: parent.hasClass(MENU), horizontal: parent.hasClass(MENU + "-horizontal"), expanded: true, length: parent.children().length }; if (referenceItem && !parent.length) { parent = $(that.renderGroup({ group: groupData, options: that.options })).appendTo(referenceItem); } if (plain || isArray(item) || item instanceof kendo.data.ObservableArray) { // is JSON items = $($.map(plain ? [ item ] : item, function (value, idx) { if (typeof value === "string") { return $(value).get(); } else { return $(that.renderItem({ group: groupData, item: extend(value, { index: idx }) })).get(); } })); } else { if (typeof item == "string" && item.charAt(0) != "<") { items = that.element.find(item); } else { items = $(item); } groups = items.find("> ul") .addClass("k-menu-group") .attr("role", "menu"); items = items.filter("li"); items.add(groups.find("> li")).each(function () { updateItemClasses(this); }); } return { items: items, group: parent }; }, remove: function (element) { element = this.attemptGetItem(element); var that = this, parent = element.parentsUntil(that.element, allItemsSelector), group = element.parent("ul:not(.k-menu)"); element.remove(); if (group && !group.children(allItemsSelector).length) { var parentItems = getParentLiItems(group); var container = group.parent(animationContainerSelector); if (container.length) { container.remove(); } else { group.remove(); } updateHasAriaPopup(parentItems); } if (parent.length) { parent = parent.eq(0); updateArrow(parent); updateFirstLast(parent); } return that; }, _openAfterLoad: function (element, dataItem) { var that = this; if(dataItem.loaded()) { that.open(element); that._loading = false; } else { dataItem.one(CHANGE, function(){ element.find(ICON_SELECTOR).removeClass("k-i-loading"); if(that._loading) { that.open(element); that._loading = false; } }); } }, open: function (element) { var that = this; var options = that.options; var horizontal = options.orientation == "horizontal"; var direction = options.direction; var isRtl = kendo.support.isRtl(that.wrapper); var overflowWrapper = that._overflowWrapper(); element = (overflowWrapper || that.element).find(element); var dataItem = that.dataSource && that.dataSource.getByUid(element.data("uid")); if(dataItem && dataItem.hasChildren && !dataItem.loaded() && !that._loading){ that._loading = true; element.find(ICON_SELECTOR).addClass("k-i-loading"); dataItem.load(); that._openAfterLoad(element, dataItem); return; } if (/^(top|bottom|default)$/.test(direction)) { if (isRtl) { direction = horizontal ? (direction + " left").replace("default", "bottom") : "left"; } else { direction = horizontal ? (direction + " right").replace("default", "bottom") : "right"; } } var visiblePopups = ">.k-popup:visible,>.k-animation-container>.k-popup:visible"; var closePopup = function () { var popup = $(this).data(KENDOPOPUP); if (popup) { // Use the built-in close method to play the hoverDelay from the options that.close($(this).closest("li.k-item"), true); } }; element.siblings() .find(visiblePopups) .each(closePopup); if (overflowWrapper) { element.find(visiblePopups).each(closePopup); } if (that.options.openOnClick) { that.clicked = true; } element.each(function () { var li = $(this); clearTimeout(li.data(TIMER)); li.data(TIMER, setTimeout(function () { var ul = li.find(".k-menu-group:first:hidden"); var popup; var overflowPopup; if (!ul[0] && overflowWrapper) { overflowPopup = that._getPopup(li); ul = overflowPopup && overflowPopup.element; } if (ul.is(":visible")) { return; } if (ul[0] && that._triggerEvent({ item: li[0], type: OPEN }) === false) { if (!ul.find(".k-menu-group")[0] && ul.children(".k-item").length > 1) { var windowHeight = $(window).height(), setScrolling = function(){ ul.css({maxHeight: windowHeight - (kendo._outerHeight(ul) - ul.height()) - kendo.getShadows(ul).bottom, overflow: "auto"}); }; if (kendo.support.browser.msie && kendo.support.browser.version <= 7) { setTimeout(setScrolling, 0); // timeout required by IE7 } else { setScrolling(); } } else { ul.css({maxHeight: "", overflow: ""}); } li.data(ZINDEX, li.css(ZINDEX)); var nextZindex = that.nextItemZIndex++; li.css(ZINDEX, nextZindex); if (that.options.scrollable) { li.parent().siblings(scrollButtonSelector).css({zIndex: ++nextZindex}); } popup = ul.data(KENDOPOPUP); var root = li.parent().hasClass(MENU), parentHorizontal = root && horizontal, directions = parseDirection(direction, root, isRtl), effects = options.animation.open.effects, openEffects = effects !== undefined ? effects : "slideIn:" + getEffectDirection(direction, root); if (!popup) { popup = ul.kendoPopup({ activate: function() { that._triggerEvent({ item: this.wrapper.parent(), type: ACTIVATE }); }, deactivate: function(e) { that._closing = false; e.sender.element // Restore opacity after fade. .removeData("targetTransform") .css({ opacity: "" }); that._triggerEvent({ item: this.wrapper.parent(), type: DEACTIVATE }); }, origin: directions.origin, position: directions.position, collision: options.popupCollision !== undefined ? options.popupCollision : (parentHorizontal ? "fit" : "fit flip"), anchor: li, appendTo: overflowWrapper || li, animation: { open: extend(true, { effects: openEffects }, options.animation.open), close: options.animation.close }, open: proxy(that._popupOpen, that), close: function (e) { that._closing = true; var li = e.sender.wrapper.parent(); if (overflowWrapper) { var popupId = e.sender.element.data(POPUP_ID_ATTR); if (popupId) { li = (overflowWrapper || that.element).find(popupOpenerSelector(popupId)); } e.sender.wrapper.children(scrollButtonSelector).hide(); } if (!that._triggerEvent({ item: li[0], type: CLOSE })) { li.css(ZINDEX, li.data(ZINDEX)); li.removeData(ZINDEX); if (that.options.scrollable) { li.parent().siblings(scrollButtonSelector).css({zIndex: ""}); } if (touch || allPointers || kendo.support.mouseAndTouchPresent) { li.removeClass(HOVERSTATE); that._removeHoverItem(); } } else { e.preventDefault(); } } }).data(KENDOPOPUP); } else { popup = ul.data(KENDOPOPUP); popup.options.origin = directions.origin; popup.options.position = directions.position; popup.options.animation.open.effects = openEffects; } ul.removeAttr("aria-hidden"); that._configurePopupOverflow(popup, li); popup._hovered = true; popup.open(); that._initPopupScrolling(popup); } }, that.options.hoverDelay)); }); return that; }, _configurePopupOverflow: function(popup, popupOpener) { var that = this; if (that.options.scrollable) { that._wrapPopupElement(popup); if (!popupOpener.attr("data-groupparent")) { var groupId = new Date().getTime(); popupOpener.attr("data-groupparent", groupId); popup.element.attr("data-group", groupId); } } }, _wrapPopupElement: function(popup){ if (!popup.element.parent().is(animationContainerSelector)) { popup.wrapper = kendo.wrap(popup.element, popup.options.autosize) .css({ overflow: "hidden", display: "block", position: "absolute" }); } }, _initPopupScrolling: function(popup, isHorizontal, skipMouseEvents) { var that = this; if (that.options.scrollable && popup.element[0].scrollHeight > popup.element[0].offsetHeight) { that._initPopupScrollButtons(popup, isHorizontal, skipMouseEvents); } }, _initPopupScrollButtons: function(popup, isHorizontal, skipMouseEvents) { var that = this; var scrollButtons = popup.wrapper.children(scrollButtonSelector); var animation = that.options.animation; var timeout = ((animation && animation.open && animation.open.duration) || 0) + DELAY; setTimeout(function() { if (!scrollButtons.length) { var backwardBtn = $(that.templates.scrollButton({direction: isHorizontal ? "left" : "up"})); var forwardBtn = $(that.templates.scrollButton({direction: isHorizontal ? "right": "down"})); scrollButtons = backwardBtn.add(forwardBtn).appendTo(popup.wrapper); that._initScrolling(popup.element, backwardBtn, forwardBtn, isHorizontal); if (!skipMouseEvents) { scrollButtons.on(MOUSEENTER + NS, function() { var overflowWrapper = that._overflowWrapper(); $(getChildPopups(popup.element, overflowWrapper)).each(function(i, p){ var popupOpener = overflowWrapper.find(popupOpenerSelector(p.data(POPUP_ID_ATTR))); that.close(popupOpener); }); }) .on(MOUSELEAVE + NS, function(){ setTimeout(function(){ if ($.isEmptyObject(that._openedPopups)) { that._closeParentPopups(popup.element); } }, DELAY); }); } } that._toggleScrollButtons(popup.element, scrollButtons.first(), scrollButtons.last(), isHorizontal); }, timeout); }, _popupOpen: function(e) { if (!this._keyTriggered) { e.sender.element.children("." + FOCUSEDSTATE).removeClass(FOCUSEDSTATE); } if (this.options.scrollable) { this._setPopupHeight(e.sender);