1 |
efrain |
1 |
{"version":3,"file":"menubar.min.js","sources":["../src/menubar.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Aria menubar functionality. Enhances a simple nested list structure into a full aria widget.\n * Based on the open ajax example: http://oaa-accessibility.org/example/26/\n *\n * @module tool_lp/menubar\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery'], function($) {\n\n /** @property {boolean} Flag to indicate if we have already registered a click event handler for the document. */\n var documentClickHandlerRegistered = false;\n\n /** @property {boolean} Flag to indicate whether there's an active, open menu. */\n var menuActive = false;\n\n /**\n * Close all open submenus anywhere in the page (there should only ever be one open at a time).\n *\n * @method closeAllSubMenus\n */\n var closeAllSubMenus = function() {\n $('.tool-lp-menu .tool-lp-sub-menu').attr('aria-hidden', 'true');\n // Every menu's closed at this point, so set the menu active flag to false.\n menuActive = false;\n };\n\n /**\n * Constructor\n *\n * @param {jQuery} menuRoot Jquery collection matching the root of the menu.\n * @param {Function[]} handlers called when a menu item is chosen.\n */\n var Menubar = function(menuRoot, handlers) {\n // Setup private class variables.\n this.menuRoot = menuRoot;\n this.handlers = handlers;\n this.rootMenus = this.menuRoot.children('li');\n this.subMenus = this.rootMenus.children('ul');\n this.subMenuItems = this.subMenus.children('li');\n this.allItems = this.rootMenus.add(this.subMenuItems);\n this.activeItem = null;\n this.isChildOpen = false;\n\n this.keys = {\n tab: 9,\n enter: 13,\n esc: 27,\n space: 32,\n left: 37,\n up: 38,\n right: 39,\n down: 40\n };\n\n this.addAriaAttributes();\n // Add the event listeners.\n this.addEventListeners();\n };\n\n /**\n * Open a submenu, first it closes all other sub-menus and sets the open direction.\n * @method openSubMenu\n * @param {Node} menu\n */\n Menubar.prototype.openSubMenu = function(menu) {\n this.setOpenDirection();\n closeAllSubMenus();\n menu.attr('aria-hidden', 'false');\n // Set menu active flag to true when a menu is opened.\n menuActive = true;\n };\n\n\n /**\n * Bind the event listeners to the DOM\n * @method addEventListeners\n */\n Menubar.prototype.addEventListeners = function() {\n var currentThis = this;\n\n // When clicking outside the menubar.\n if (documentClickHandlerRegistered === false) {\n $(document).click(function() {\n // Check if a menu is opened.\n if (menuActive) {\n // Close menu.\n closeAllSubMenus();\n }\n });\n // Set this flag to true so that we won't need to add a document click handler for the other Menubar instances.\n documentClickHandlerRegistered = true;\n }\n\n // Hovers.\n this.subMenuItems.mouseenter(function() {\n $(this).addClass('menu-hover');\n return true;\n });\n\n this.subMenuItems.mouseout(function() {\n $(this).removeClass('menu-hover');\n return true;\n });\n\n // Mouse listeners.\n this.allItems.click(function(e) {\n return currentThis.handleClick($(this), e);\n });\n\n // Key listeners.\n this.allItems.keydown(function(e) {\n return currentThis.handleKeyDown($(this), e);\n });\n\n this.allItems.focus(function() {\n return currentThis.handleFocus($(this));\n });\n\n this.allItems.blur(function() {\n return currentThis.handleBlur($(this));\n });\n };\n\n /**\n * Process click events for the top menus.\n *\n * @method handleClick\n * @param {Object} item is the jquery object of the item firing the event\n * @param {Event} e is the associated event object\n * @return {boolean} Returns false\n */\n Menubar.prototype.handleClick = function(item, e) {\n e.stopPropagation();\n\n var parentUL = item.parent();\n\n if (parentUL.is('.tool-lp-menu')) {\n // Toggle the child menu open/closed.\n if (item.children('ul').first().attr('aria-hidden') == 'true') {\n this.openSubMenu(item.children('ul').first());\n } else {\n item.children('ul').first().attr('aria-hidden', 'true');\n }\n } else {\n // Remove hover and focus styling.\n this.allItems.removeClass('menu-hover menu-focus');\n\n // Clear the active item.\n this.activeItem = null;\n\n // Close the menu.\n this.menuRoot.find('ul').not('.root-level').attr('aria-hidden', 'true');\n // Follow any link, or call the click handlers.\n var anchor = item.find('a').first();\n var clickEvent = new $.Event('click');\n clickEvent.target = anchor;\n var eventHandled = false;\n if (this.handlers) {\n $.each(this.handlers, function(selector, handler) {\n if (eventHandled) {\n return;\n }\n if (item.find(selector).length > 0) {\n var callable = $.proxy(handler, anchor);\n // False means stop propogatting events.\n eventHandled = (callable(clickEvent) === false) || clickEvent.isDefaultPrevented();\n }\n });\n }\n // If we didn't find a handler, and the HREF is # that probably means that\n // we are handling it from somewhere else. Let's just do nothing in that case.\n if (!eventHandled && anchor.attr('href') !== '#') {\n window.location.href = anchor.attr('href');\n }\n }\n return false;\n };\n\n /*\n * Process focus events for the menu.\n *\n * @method handleFocus\n * @param {Object} item is the jquery object of the item firing the event\n * @return boolean Returns false\n */\n Menubar.prototype.handleFocus = function(item) {\n\n // If activeItem is null, we are getting focus from outside the menu. Store\n // the item that triggered the event.\n if (this.activeItem === null) {\n this.activeItem = item;\n } else if (item[0] != this.activeItem[0]) {\n return true;\n }\n\n // Get the set of jquery objects for all the parent items of the active item.\n var parentItems = this.activeItem.parentsUntil('ul.tool-lp-menu').filter('li');\n\n // Remove focus styling from all other menu items.\n this.allItems.removeClass('menu-focus');\n\n // Add focus styling to the active item.\n this.activeItem.addClass('menu-focus');\n\n // Add focus styling to all parent items.\n parentItems.addClass('menu-focus');\n\n // If the bChildOpen flag has been set, open the active item's child menu (if applicable).\n if (this.isChildOpen === true) {\n\n var itemUL = item.parent();\n\n // If the itemUL is a root-level menu and item is a parent item,\n // show the child menu.\n if (itemUL.is('.tool-lp-menu') && (item.attr('aria-haspopup') == 'true')) {\n this.openSubMenu(item.children('ul').first());\n }\n }\n\n return true;\n };\n\n /*\n * Process blur events for the menu.\n *\n * @method handleBlur\n * @param {Object} item is the jquery object of the item firing the event\n * @return boolean Returns false\n */\n Menubar.prototype.handleBlur = function(item) {\n item.removeClass('menu-focus');\n\n return true;\n };\n\n /*\n * Determine if the menu should open to the left, or the right,\n * based on the screen size and menu position.\n * @method setOpenDirection\n */\n Menubar.prototype.setOpenDirection = function() {\n var pos = this.menuRoot.offset();\n var isRTL = $(document.body).hasClass('dir-rtl');\n var openLeft = true;\n var heightmenuRoot = this.rootMenus.outerHeight();\n var widthmenuRoot = this.rootMenus.outerWidth();\n // Sometimes the menuMinWidth is not enough to figure out if menu exceeds the window width.\n // So we have to calculate the real menu width.\n var subMenuContainer = this.rootMenus.find('ul.tool-lp-sub-menu');\n\n // Reset margins.\n subMenuContainer.css('margin-right', '');\n subMenuContainer.css('margin-left', '');\n subMenuContainer.css('margin-top', '');\n\n subMenuContainer.attr('aria-hidden', false);\n var menuRealWidth = subMenuContainer.outerWidth(),\n menuRealHeight = subMenuContainer.outerHeight();\n\n var margintop = null,\n marginright = null,\n marginleft = null;\n var top = pos.top - $(window).scrollTop();\n // Top is the same for RTL and LTR.\n if (top + menuRealHeight > $(window).height()) {\n margintop = menuRealHeight + heightmenuRoot;\n subMenuContainer.css('margin-top', '-' + margintop + 'px');\n }\n\n if (isRTL) {\n if (pos.left - menuRealWidth < 0) {\n marginright = menuRealWidth - widthmenuRoot;\n subMenuContainer.css('margin-right', '-' + marginright + 'px');\n }\n } else {\n if (pos.left + menuRealWidth > $(window).width()) {\n marginleft = menuRealWidth - widthmenuRoot;\n subMenuContainer.css('margin-left', '-' + marginleft + 'px');\n }\n }\n\n if (openLeft) {\n this.menuRoot.addClass('tool-lp-menu-open-left');\n } else {\n this.menuRoot.removeClass('tool-lp-menu-open-left');\n }\n\n };\n\n /*\n * Process keyDown events for the menu.\n *\n * @method handleKeyDown\n * @param {Object} item is the jquery object of the item firing the event\n * @param {Event} e is the associated event object\n * @return boolean Returns false if consuming the event\n */\n Menubar.prototype.handleKeyDown = function(item, e) {\n\n if (e.altKey || e.ctrlKey) {\n // Modifier key pressed: Do not process.\n return true;\n }\n\n switch (e.keyCode) {\n case this.keys.tab: {\n\n // Hide all menu items and update their aria attributes.\n this.menuRoot.find('ul').attr('aria-hidden', 'true');\n\n // Remove focus styling from all menu items.\n this.allItems.removeClass('menu-focus');\n\n this.activeItem = null;\n\n this.isChildOpen = false;\n\n break;\n }\n case this.keys.esc: {\n var itemUL = item.parent();\n\n if (itemUL.is('.tool-lp-menu')) {\n // Hide the child menu and update the aria attributes.\n item.children('ul').first().attr('aria-hidden', 'true');\n } else {\n\n // Move up one level.\n this.activeItem = itemUL.parent();\n\n // Reset the isChildOpen flag.\n this.isChildOpen = false;\n\n // Set focus on the new item.\n this.activeItem.focus();\n\n // Hide the active menu and update the aria attributes.\n itemUL.attr('aria-hidden', 'true');\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.enter:\n case this.keys.space: {\n // Trigger click handler.\n return this.handleClick(item, e);\n }\n\n case this.keys.left: {\n\n this.activeItem = this.moveToPrevious(item);\n\n this.activeItem.focus();\n\n e.stopPropagation();\n return false;\n }\n case this.keys.right: {\n\n this.activeItem = this.moveToNext(item);\n\n this.activeItem.focus();\n\n e.stopPropagation();\n return false;\n }\n case this.keys.up: {\n\n this.activeItem = this.moveUp(item);\n\n this.activeItem.focus();\n\n e.stopPropagation();\n return false;\n }\n case this.keys.down: {\n\n this.activeItem = this.moveDown(item);\n\n this.activeItem.focus();\n\n e.stopPropagation();\n return false;\n }\n }\n\n return true;\n\n };\n\n\n /**\n * Move to the next menu level.\n * This will be either the next root-level menu or the child of a menu parent. If\n * at the root level and the active item is the last in the menu, this function will loop\n * to the first menu item.\n *\n * If the menu is a horizontal menu, the first child element of the newly selected menu will\n * be selected\n *\n * @method moveToNext\n * @param {Object} item is the active menu item\n * @return {Object} Returns the item to move to. Returns item is no move is possible\n */\n Menubar.prototype.moveToNext = function(item) {\n // Item's containing menu.\n var itemUL = item.parent();\n\n // The items in the currently active menu.\n var menuItems = itemUL.children('li');\n\n // The number of items in the active menu.\n var menuNum = menuItems.length;\n // The items index in its menu.\n var menuIndex = menuItems.index(item);\n var newItem = null;\n var childMenu = null;\n\n if (itemUL.is('.tool-lp-menu')) {\n // This is the root level move to next sibling. This will require closing\n // the current child menu and opening the new one.\n\n if (menuIndex < menuNum - 1) {\n // Not the last root menu.\n newItem = item.next();\n } else { // Wrap to first item.\n newItem = menuItems.first();\n }\n\n // Close the current child menu (if applicable).\n if (item.attr('aria-haspopup') == 'true') {\n\n childMenu = item.children('ul').first();\n\n if (childMenu.attr('aria-hidden') == 'false') {\n // Update the child menu's aria-hidden attribute.\n childMenu.attr('aria-hidden', 'true');\n this.isChildOpen = true;\n }\n }\n\n // Remove the focus styling from the current menu.\n item.removeClass('menu-focus');\n\n // Open the new child menu (if applicable).\n if ((newItem.attr('aria-haspopup') === 'true') && (this.isChildOpen === true)) {\n\n childMenu = newItem.children('ul').first();\n\n // Update the child's aria-hidden attribute.\n this.openSubMenu(childMenu);\n }\n } else {\n // This is not the root level. If there is a child menu to be moved into, do that;\n // otherwise, move to the next root-level menu if there is one.\n if (item.attr('aria-haspopup') == 'true') {\n\n childMenu = item.children('ul').first();\n\n newItem = childMenu.children('li').first();\n\n // Show the child menu and update its aria attributes.\n this.openSubMenu(childMenu);\n } else {\n // At deepest level, move to the next root-level menu.\n\n var parentMenus = null;\n var rootItem = null;\n\n // Get list of all parent menus for item, up to the root level.\n parentMenus = item.parentsUntil('ul.tool-lp-menu').filter('ul').not('.tool-lp-menu');\n\n // Hide the current menu and update its aria attributes accordingly.\n parentMenus.attr('aria-hidden', 'true');\n\n // Remove the focus styling from the active menu.\n parentMenus.find('li').removeClass('menu-focus');\n parentMenus.last().parent().removeClass('menu-focus');\n\n // The containing root for the menu.\n rootItem = parentMenus.last().parent();\n\n menuIndex = this.rootMenus.index(rootItem);\n\n // If this is not the last root menu item, move to the next one.\n if (menuIndex < this.rootMenus.length - 1) {\n newItem = rootItem.next();\n } else {\n // Loop.\n newItem = this.rootMenus.first();\n }\n\n // Add the focus styling to the new menu.\n newItem.addClass('menu-focus');\n\n if (newItem.attr('aria-haspopup') == 'true') {\n childMenu = newItem.children('ul').first();\n\n newItem = childMenu.children('li').first();\n\n // Show the child menu and update it's aria attributes.\n this.openSubMenu(childMenu);\n this.isChildOpen = true;\n }\n }\n }\n\n return newItem;\n };\n\n /**\n * Member function to move to the previous menu level.\n * This will be either the previous root-level menu or the child of a menu parent. If\n * at the root level and the active item is the first in the menu, this function will loop\n * to the last menu item.\n *\n * If the menu is a horizontal menu, the first child element of the newly selected menu will\n * be selected\n *\n * @method moveToPrevious\n * @param {Object} item is the active menu item\n * @return {Object} Returns the item to move to. Returns item is no move is possible\n */\n Menubar.prototype.moveToPrevious = function(item) {\n // Item's containing menu.\n var itemUL = item.parent();\n // The items in the currently active menu.\n var menuItems = itemUL.children('li');\n // The items index in its menu.\n var menuIndex = menuItems.index(item);\n var newItem = null;\n var childMenu = null;\n\n if (itemUL.is('.tool-lp-menu')) {\n // This is the root level move to previous sibling. This will require closing\n // the current child menu and opening the new one.\n\n if (menuIndex > 0) {\n // Not the first root menu.\n newItem = item.prev();\n } else {\n // Wrap to last item.\n newItem = menuItems.last();\n }\n\n // Close the current child menu (if applicable).\n if (item.attr('aria-haspopup') == 'true') {\n childMenu = item.children('ul').first();\n\n if (childMenu.attr('aria-hidden') == 'false') {\n // Update the child menu's aria-hidden attribute.\n childMenu.attr('aria-hidden', 'true');\n this.isChildOpen = true;\n }\n }\n\n // Remove the focus styling from the current menu.\n item.removeClass('menu-focus');\n\n // Open the new child menu (if applicable).\n if ((newItem.attr('aria-haspopup') === 'true') && (this.isChildOpen === true)) {\n\n childMenu = newItem.children('ul').first();\n\n // Update the child's aria-hidden attribute.\n this.openSubMenu(childMenu);\n\n }\n } else {\n // This is not the root level. If there is a parent menu that is not the\n // root menu, move up one level; otherwise, move to first item of the previous\n // root menu.\n\n var parentLI = itemUL.parent();\n var parentUL = parentLI.parent();\n\n // If this is a vertical menu or is not the first child menu\n // of the root-level menu, move up one level.\n if (!parentUL.is('.tool-lp-menu')) {\n\n newItem = itemUL.parent();\n\n // Hide the active menu and update aria-hidden.\n itemUL.attr('aria-hidden', 'true');\n\n // Remove the focus highlight from the item.\n item.removeClass('menu-focus');\n\n } else {\n // Move to previous root-level menu.\n\n // Hide the current menu and update the aria attributes accordingly.\n itemUL.attr('aria-hidden', 'true');\n\n // Remove the focus styling from the active menu.\n item.removeClass('menu-focus');\n parentLI.removeClass('menu-focus');\n\n menuIndex = this.rootMenus.index(parentLI);\n\n if (menuIndex > 0) {\n // Move to the previous root-level menu.\n newItem = parentLI.prev();\n } else {\n // Loop to last root-level menu.\n newItem = this.rootMenus.last();\n }\n\n // Add the focus styling to the new menu.\n newItem.addClass('menu-focus');\n\n if (newItem.attr('aria-haspopup') == 'true') {\n childMenu = newItem.children('ul').first();\n\n // Show the child menu and update it's aria attributes.\n this.openSubMenu(childMenu);\n this.isChildOpen = true;\n\n newItem = childMenu.children('li').first();\n }\n }\n }\n\n return newItem;\n };\n\n /**\n * Member function to select the next item in a menu.\n * If the active item is the last in the menu, this function will loop to the\n * first menu item.\n *\n * @method moveDown\n * @param {Object} item is the active menu item\n * @param {String} startChr is the character to attempt to match against the beginning of the\n * menu item titles. If found, focus moves to the next menu item beginning with that character.\n * @return {Object} Returns the item to move to. Returns item is no move is possible\n */\n Menubar.prototype.moveDown = function(item, startChr) {\n // Item's containing menu.\n var itemUL = item.parent();\n // The items in the currently active menu.\n var menuItems = itemUL.children('li').not('.separator');\n // The number of items in the active menu.\n var menuNum = menuItems.length;\n // The items index in its menu.\n var menuIndex = menuItems.index(item);\n var newItem = null;\n var newItemUL = null;\n\n if (itemUL.is('.tool-lp-menu')) {\n // This is the root level menu.\n\n if (item.attr('aria-haspopup') != 'true') {\n // No child menu to move to.\n return item;\n }\n\n // Move to the first item in the child menu.\n newItemUL = item.children('ul').first();\n newItem = newItemUL.children('li').first();\n\n // Make sure the child menu is visible.\n this.openSubMenu(newItemUL);\n\n return newItem;\n }\n\n // If $item is not the last item in its menu, move to the next item. If startChr is specified, move\n // to the next item with a title that begins with that character.\n if (startChr) {\n var match = false;\n var curNdx = menuIndex + 1;\n\n // Check if the active item was the last one on the list.\n if (curNdx == menuNum) {\n curNdx = 0;\n }\n\n // Iterate through the menu items (starting from the current item and wrapping) until a match is found\n // or the loop returns to the current menu item.\n while (curNdx != menuIndex) {\n\n var titleChr = menuItems.eq(curNdx).html().charAt(0);\n\n if (titleChr.toLowerCase() == startChr) {\n match = true;\n break;\n }\n\n curNdx = curNdx + 1;\n\n if (curNdx == menuNum) {\n // Reached the end of the list, start again at the beginning.\n curNdx = 0;\n }\n }\n\n if (match === true) {\n newItem = menuItems.eq(curNdx);\n\n // Remove the focus styling from the current item.\n item.removeClass('menu-focus');\n\n return newItem;\n } else {\n return item;\n }\n } else {\n if (menuIndex < menuNum - 1) {\n newItem = menuItems.eq(menuIndex + 1);\n } else {\n newItem = menuItems.first();\n }\n }\n\n // Remove the focus styling from the current item.\n item.removeClass('menu-focus');\n\n return newItem;\n };\n\n /**\n * Function moveUp() is a member function to select the previous item in a menu.\n * If the active item is the first in the menu, this function will loop to the\n * last menu item.\n *\n * @method moveUp\n * @param {Object} item is the active menu item\n * @return {Object} Returns the item to move to. Returns item is no move is possible\n */\n Menubar.prototype.moveUp = function(item) {\n // Item's containing menu.\n var itemUL = item.parent();\n // The items in the currently active menu.\n var menuItems = itemUL.children('li').not('.separator');\n // The items index in its menu.\n var menuIndex = menuItems.index(item);\n var newItem = null;\n\n if (itemUL.is('.tool-lp-menu')) {\n // This is the root level menu.\n // Nothing to do.\n return item;\n }\n\n // If item is not the first item in its menu, move to the previous item.\n if (menuIndex > 0) {\n newItem = menuItems.eq(menuIndex - 1);\n } else {\n // Loop to top of menu.\n newItem = menuItems.last();\n }\n\n // Remove the focus styling from the current item.\n item.removeClass('menu-focus');\n\n return newItem;\n };\n\n /**\n * Enhance the dom with aria attributes.\n * @method addAriaAttributes\n */\n Menubar.prototype.addAriaAttributes = function() {\n this.menuRoot.attr('role', 'menubar');\n this.rootMenus.attr('role', 'menuitem');\n this.rootMenus.attr('tabindex', '0');\n this.rootMenus.attr('aria-haspopup', 'true');\n this.subMenus.attr('role', 'menu');\n this.subMenus.attr('aria-hidden', 'true');\n this.subMenuItems.attr('role', 'menuitem');\n this.subMenuItems.attr('tabindex', '-1');\n\n // For CSS styling and effects.\n this.menuRoot.addClass('tool-lp-menu');\n this.allItems.addClass('tool-lp-menu-item');\n this.rootMenus.addClass('tool-lp-root-menu');\n this.subMenus.addClass('tool-lp-sub-menu');\n this.subMenuItems.addClass('dropdown-item');\n };\n\n return /** @alias module:tool_lp/menubar */ {\n /**\n * Create a menu bar object for every node matching the selector.\n *\n * The expected DOM structure is shown below.\n * <ul> <- This is the target of the selector parameter.\n * <li> <- This is repeated for each top level menu.\n * Text <- This is the text for the top level menu.\n * <ul> <- This is a list of the entries in this top level menu.\n * <li> <- This is repeated for each menu entry.\n * <a href=\"someurl\">Choice 1</a> <- The anchor for the menu.\n * </li>\n * </ul>\n * </li>\n * </ul>\n *\n * @method enhance\n * @param {String} selector - The selector for the outer most menu node.\n * @param {Function} handler - Javascript handler for when a menu item was chosen. If the\n * handler returns true (or does not exist), the\n * menu will look for an anchor with a link to follow.\n * For example, if the menu entry has a \"data-action\" attribute\n * and we want to call a javascript function when that entry is chosen,\n * we could pass a list of handlers like this:\n * { \"[data-action='add']\" : callAddFunction }\n */\n enhance: function(selector, handler) {\n $(selector).each(function(index, element) {\n var menuRoot = $(element);\n // Don't enhance the same menu twice.\n if (menuRoot.data(\"menubarEnhanced\") !== true) {\n (new Menubar(menuRoot, handler));\n menuRoot.data(\"menubarEnhanced\", true);\n }\n });\n },\n\n /**\n * Handy function to close all open menus anywhere on the page.\n * @method closeAll\n */\n closeAll: closeAllSubMenus\n };\n});\n"],"names":["define","$","documentClickHandlerRegistered","menuActive","closeAllSubMenus","attr","Menubar","menuRoot","handlers","rootMenus","this","children","subMenus","subMenuItems","allItems","add","activeItem","isChildOpen","keys","tab","enter","esc","space","left","up","right","down","addAriaAttributes","addEventListeners","prototype","openSubMenu","menu","setOpenDirection","currentThis","document","click","mouseenter","addClass","mouseout","removeClass","e","handleClick","keydown","handleKeyDown","focus","handleFocus","blur","handleBlur","item","stopPropagation","parent","is","first","find","not","anchor","clickEvent","Event","target","eventHandled","each","selector","handler","length","callable","proxy","isDefaultPrevented","window","location","href","parentItems","parentsUntil","filter","pos","offset","isRTL","body","hasClass","heightmenuRoot","outerHeight","widthmenuRoot","outerWidth","subMenuContainer","css","menuRealWidth","menuRealHeight","margintop","marginright","marginleft","top","scrollTop","height","width","altKey","ctrlKey","keyCode","itemUL","moveToPrevious","moveToNext","moveUp","moveDown","menuItems","menuNum","menuIndex","index","newItem","childMenu","next","parentMenus","rootItem","last","prev","parentLI","startChr","newItemUL","match","curNdx","eq","html","charAt","toLowerCase","enhance","element","data","closeAll"],"mappings":"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"}
|