[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: hs-mega-menu.js
/* * HSMegaMenu Plugin * @version: 2.0.1 (Sun, 1 Nov 2021) * @author: HtmlStream * @event-namespace: .HSMegaMenu * @license: Htmlstream Libraries (https://htmlstream.com/) * Copyright 2021 Htmlstream */ import objectAssignDeep from "./methods/object-assign-deep"; import getType from "./methods/get-type"; import smartPosition from "./methods/smart-position"; import desktopCSSAnimationEnable from "./methods/desktop-css-animation-enable"; import desktopMouseEnterEventListener from "./methods/desktop-mouseenter-event-listener"; import desktopMouseLeaveEventListener from "./methods/desktop-mouseleave-event-listener"; import desktopClickEventListener from "./methods/desktop-click-event-listener"; import mobileClickEventListener from "./methods/mobile-click-event-listener"; const dataAttributeName = 'data-hs-mega-menu-options' const defaults = { eventType: 'hover', direction: 'horizontal', breakpoint: 'lg', rtl: false, isMenuOpened: false, sideBarRatio: 1 / 4, pageContainer: document.getElementsByTagName('body'), mobileSpeed: 400, duration: 300, delay: 0, itemOptions: { megaMenuTimeOut: null, desktop: { animation: 'animated', animationIn: 'slideInUp', animationOut: false, position: null, maxWidth: null } }, classMap: { rtl: '.hs-rtl', reversed: '.hs-reversed', initialized: '.hs-menu-initialized', mobileState: '.hs-mobile-state', invoker: '.hs-mega-menu-invoker', subMenu: '.hs-sub-menu', hasSubMenu: '.hs-has-sub-menu', hasSubMenuActive: '.hs-sub-menu-opened', megaMenu: '.hs-mega-menu', hasMegaMenu: '.hs-has-mega-menu', hasMegaMenuActive: '.hs-mega-menu-opened' } } export default class HSMegaMenu { constructor(el, options, id) { this.collection = [] const that = this let elems if (el instanceof HTMLElement) { elems = [el] } else if (el instanceof Object) { elems = el } else { elems = document.querySelectorAll(el) } for (let i = 0; i < elems.length; i += 1) { that.addToCollection(elems[i], options, id || elems[i].id) } if (!that.collection.length) { return false } // initialization calls that._init() return this } _init() { const that = this; for (let i = 0; i < that.collection.length; i += 1) { let _$el let _options if (that.collection[i].hasOwnProperty('$initializedEl')) { continue } _$el = that.collection[i].$el _options = that.collection[i].options _options.state = null; // Resolution list var resolutionsList = { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200 }; // Keycodes var ESC_KEYCODE = 27, TAB_KEYCODE = 9, ENTER_KEYCODE = 13, SPACE_KEYCODE = 32, ARROW_UP_KEYCODE = 38, ARROW_DOWN_KEYCODE = 40, ARROW_RIGHT_KEYCODE = 39, ARROW_LEFT_KEYCODE = 37; // Prevent scroll const preventScroll = (keycode) => { return e => { if (e.which === keycode) { e.preventDefault(); } }; } // Get Item Settings const getItemSettings = ($el) => { if (!$el) return false; let dataSettings = $el.hasAttribute('data-hs-mega-menu-item-options') ? JSON.parse($el.getAttribute('data-hs-mega-menu-item-options')) : {}, itemSettings = _options.itemOptions; itemSettings = Object.assign({}, itemSettings,dataSettings); itemSettings.activeItemClass = () => { return getType($el, _options) === 'mega-menu' ? _options.classMap.hasMegaMenuActive : _options.classMap.hasSubMenuActive; }; return itemSettings; } const stateDetection = () => { if (window.innerWidth < resolutionsList[_options.breakpoint]) { this.state = 'mobile'; } else { this.state = 'desktop'; } } stateDetection() // State Detection window.addEventListener('resize', () => { stateDetection() }) // Set RTL if (_options.rtl) { _$el.addClass(_options.classMap.rtl.slice(1)); } // Init Menu Items _$el.querySelectorAll(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`).forEach(el => { this.MegaMenuItem(el, el.querySelector(_options.classMap[getType(el, _options) === 'mega-menu' ? 'megaMenu' : 'subMenu']), _options); }); // Add Initialized Classes _$el.classList.add(`${_options.classMap.initialized.slice(1)}`, `hs-menu-${_options.direction}`); // ***** // Start: ACCESSIBILITY // ***** var myPreventScrollSpace = preventScroll(SPACE_KEYCODE), myPreventScrollDown = preventScroll(ARROW_DOWN_KEYCODE), myPreventScrollUp = preventScroll(ARROW_UP_KEYCODE); let $items, index, state = null; document.addEventListener('keyup', () => { window.removeEventListener('keydown', myPreventScrollSpace, false); window.removeEventListener('keydown', myPreventScrollUp, false); window.removeEventListener('keydown', myPreventScrollDown, false); }); document.addEventListener('keyup', e => { if (!e.target.closest(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`) || e.target.closest('input')) return false // // Start: PREVENT SCROLL // e.preventDefault(); e.stopPropagation(); window.addEventListener('keydown', myPreventScrollSpace, false); window.addEventListener('keydown', myPreventScrollUp, false); window.addEventListener('keydown', myPreventScrollDown, false); // // End: PREVENT SCROLL // // // Start: ELEMENT DETECTION // if (e.target.classList.contains(_options.classMap.invoker.slice(1)) && !e.target.closest([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`])) { // console.log('Top level'); if (state !== 'topLevel') { state = 'topLevel'; } $items = [].slice.call(e.target.parentNode.parentNode.querySelectorAll(_options.classMap.invoker)).filter(item => { if (!item.closest([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`])) { return item.offsetParent !== null; } }); } else if (e.target.closest([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`]) && e.target.parentNode.querySelector(`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`)) { // console.log('Has submenu and not top level'); if (state !== 'hasSubmenu') { state = 'hasSubmenu'; } $items = [].slice.call(e.target.parentNode.parentNode.querySelectorAll(_options.classMap.invoker)).filter(item => { return item.offsetParent !== null; }); } else { // console.log('Just element'); if (state !== 'simple') { state = 'simple'; } $items = [].slice.call(e.target.closest([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`]).querySelectorAll('a, button')).filter(item => { return item.offsetParent !== null; }); } // // End: ELEMENT DETECTION // index = $items.indexOf(e.target); // // Start: TOP LEVEL // // Left if ( state === 'topLevel' && e.which === ARROW_LEFT_KEYCODE && index > 0 ) { index--; } // Right if ( state === 'topLevel' && e.which === ARROW_RIGHT_KEYCODE && index < ($items.length - 1) ) { index++; } // Open Sub if ( state === 'topLevel' && ( e.which === ARROW_DOWN_KEYCODE || e.which === SPACE_KEYCODE || e.which === ENTER_KEYCODE ) ) { if (!e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`])) { desktopMouseEnterEventListener(e.target.parentNode, e.target.parentNode.querySelector(([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`])), _options, getItemSettings(e.target.parentNode))(); } else if (e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`])) { e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`]).querySelectorAll('a')[0].focus() return; } } // Close Siblings if ( state === 'topLevel' && ( e.which === TAB_KEYCODE || e.which === ARROW_RIGHT_KEYCODE || e.which === ARROW_LEFT_KEYCODE ) && e.target.closest(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`).parentNode.querySelector(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`) ) { desktopMouseLeaveEventListener(e.target.closest(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`), e.target.closest(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`).parentNode.querySelector(`${_options.classMap.hasMegaMenuActive} > ${_options.classMap.megaMenu}, ${_options.classMap.hasSubMenuActive} > ${_options.classMap.subMenu}`), _options, getItemSettings(e.target.closest(`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`)))(); } // // End: TOP LEVEL // // // Start: HAS SUB-MENU BUT NOT TOP LEVEL // // Up if ( state === 'hasSubmenu' && e.which === ARROW_UP_KEYCODE && index > 0 ) { index--; } // Down if ( state === 'hasSubmenu' && e.which === ARROW_DOWN_KEYCODE && index < ($items.length - 1) ) { index++; } // Open Sub if ( state === 'hasSubmenu' && ( e.which === ARROW_LEFT_KEYCODE || e.which === ARROW_RIGHT_KEYCODE || e.which === SPACE_KEYCODE || e.which === ENTER_KEYCODE ) ) { if (!e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`])) { desktopMouseEnterEventListener(e.target.parentNode, e.target.parentNode.querySelector(([`${_options.classMap.subMenu}, ${_options.classMap.megaMenu}`])), _options, getItemSettings(e.target.parentNode))(); } else if (e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`])) { e.target.parentNode.querySelector([`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`]).querySelectorAll('a')[0].focus() return; } } // Close Siblings if ( state === 'hasSubmenu' && ( e.which === TAB_KEYCODE || e.which === ARROW_DOWN_KEYCODE || e.which === ARROW_UP_KEYCODE ) && e.target.closest([`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`]).parentNode.querySelectorAll(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`).length ) { desktopMouseLeaveEventListener(e.target.closest([`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`]), e.target.closest([`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`]).parentNode.querySelector(`${_options.classMap.hasMegaMenuActive} > ${_options.classMap.megaMenu}, ${_options.classMap.hasSubMenuActive} > ${_options.classMap.subMenu}`), _options, getItemSettings(e.target.closest([`${_options.classMap.hasMegaMenu}, ${_options.classMap.hasSubMenu}`])))(); } // // End: HAS SUB-MENU BUT NOT TOP LEVEL // // // Start: SIMPLE // // Left, Up if ( state === 'simple' && ( e.which === ARROW_UP_KEYCODE ) && index > 0 ) { index--; } // Right, Down if ( state === 'simple' && ( e.which === ARROW_DOWN_KEYCODE ) && index < ($items.length - 1) ) { index++; } // Close Siblings if ( state === 'simple' && ( e.which === ARROW_RIGHT_KEYCODE || e.which === ARROW_LEFT_KEYCODE ) && e.target.closest(_options.classMap.hasSubMenu).parentNode.querySelector(_options.classMap.subMenu) ) { e.target.closest(_options.classMap.hasSubMenu).querySelector(_options.classMap.invoker).focus(); desktopMouseLeaveEventListener(e.target.closest(_options.classMap.hasSubMenu), e.target.closest(_options.classMap.hasSubMenu).parentNode.querySelector(`${_options.classMap.hasSubMenuActive} > ${_options.classMap.subMenu}`), _options, getItemSettings(e.target.closest(_options.classMap.hasSubMenu)))(); return; } // // End: SIMPLE // // Close Self if ( e.which === ESC_KEYCODE && this.state === 'desktop' && document.querySelector(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`) ) { desktopMouseLeaveEventListener( document.querySelector(`${_options.classMap.hasMegaMenuActive}, ${_options.classMap.hasSubMenuActive}`), document.querySelector(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`), _options, getItemSettings(document.querySelector(`${_options.classMap.hasMegaMenuActive}, ${_options.classMap.hasSubMenuActive}`)) )(); return; } // Reset index if (index < 0) { index = 0; } $items[index].focus(); }); document.addEventListener('keyup', e => { // Close All if ( e.which === TAB_KEYCODE && document.querySelector(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`) ) { desktopMouseLeaveEventListener( document.querySelector(`${_options.classMap.hasMegaMenuActive}, ${_options.classMap.hasSubMenuActive}`), document.querySelector(`${_options.classMap.megaMenu}.${_options.itemOptions.desktop.animationIn}, ${_options.classMap.subMenu}.${_options.itemOptions.desktop.animationIn}`), _options, getItemSettings(document.querySelector(`${_options.classMap.hasMegaMenuActive}, ${_options.classMap.hasSubMenuActive}`)) )(); } }); // ***** // End: ACCESSIBILITY // ***** that.collection[i].$initializedEl = _options } } MegaMenuItem(el, menu, params) { var context = this, settings = params, itemDataSettings = el.hasAttribute('data-hs-mega-menu-item-options') ? JSON.parse(el.getAttribute('data-hs-mega-menu-item-options')) : {}, $el = el, $menu = menu; let itemSettings = { eventType: itemDataSettings.eventType ? itemDataSettings.eventType : settings.eventType, megaMenuTimeOut: null, desktop: { animation: 'animated', animationIn: 'slideInUp', animationOut: false, position: null, maxWidth: null } }; itemSettings = objectAssignDeep({}, settings, itemSettings, itemDataSettings); itemSettings.activeItemClass = () => { return getType($el, itemSettings) === 'mega-menu' ? itemSettings.classMap.hasMegaMenuActive : itemSettings.classMap.hasSubMenuActive; }; // Set Menu Breakpoint Class $menu.classList.add(getType($el, itemSettings) === 'mega-menu' ? `hs-mega-menu-desktop-${itemSettings.breakpoint}` : `hs-sub-menu-desktop-${itemSettings.breakpoint}`); // Listeners let myDesktopCSSAnimationEnable = desktopCSSAnimationEnable($menu, itemSettings), myDesktopMouseEnterEventListener = desktopMouseEnterEventListener($el, $menu, settings, itemSettings), myDesktopMouseLeaveEventListener = desktopMouseLeaveEventListener($el, $menu, settings, itemSettings), myDesktopClickEventListener = desktopClickEventListener($el, $menu, settings, itemSettings), myMobileClickEventListener = mobileClickEventListener($el, $menu, settings, itemSettings); let mobileListeners = () => { // Remove Desktop Listeners $menu.removeEventListener('animationend', myDesktopCSSAnimationEnable, false); $menu.removeEventListener('webkitAnimationEnd', myDesktopCSSAnimationEnable, false); $el.removeEventListener('mouseenter', myDesktopMouseEnterEventListener, false); $el.removeEventListener('mouseleave', myDesktopMouseLeaveEventListener, false); // $el.children(settings.classMap.invoker)[0].removeEventListener('focus', myDesktopMouseEnterEventListener, false); $el.querySelector(itemSettings.classMap.invoker).removeEventListener('click', myDesktopClickEventListener, false); // Add Mobile Listeners $el.querySelector(itemSettings.classMap.invoker).addEventListener('click', myMobileClickEventListener, false); }, desktopListeners = () => { // Remove Mobile Listeners $el.querySelector(itemSettings.classMap.invoker).removeEventListener('click', myMobileClickEventListener, false); // Add Desktop Listeners $menu.addEventListener('animationend', myDesktopCSSAnimationEnable, false); $menu.addEventListener('webkitAnimationEnd', myDesktopCSSAnimationEnable, false); if (itemSettings.eventType === 'hover') { $el.addEventListener('mouseenter', myDesktopMouseEnterEventListener, false); $el.addEventListener('mouseleave', myDesktopMouseLeaveEventListener, false); } if (itemSettings.eventType === 'click') { $el.querySelector(itemSettings.classMap.invoker).addEventListener('click', myDesktopClickEventListener, false); } }; if (itemSettings.desktop.maxWidth) { $menu.style.maxWidth = itemSettings.desktop.maxWidth } if (itemSettings.desktop.position) { $menu.classList.add(`hs-position-${itemSettings.desktop.position}`); } // Document Events document.addEventListener('click', e => { if (!e.target.closest([itemSettings.classMap.subMenu, itemSettings.classMap.megaMenu, itemSettings.classMap.invoker]) && context.state === 'desktop') { $el.classList.remove(itemSettings.activeItemClass().slice(1)); $menu.classList.remove(itemSettings.desktop.animationIn); if (itemSettings.animationOut) { $menu.classList.add(itemSettings.desktop.animationOut); } else { $menu.style.display = 'none'; } } }); // Resize and Scroll Events window.addEventListener('resize', () => { if (context.state === 'desktop') { smartPosition($menu, itemSettings); } }); const resizeDetection = () => { if (context.state === 'mobile') { $menu.classList.remove(itemSettings.desktop.animation) $menu.style.animationDuration = '' mobileListeners() } else if (context.state === 'desktop') { $menu.classList.add(itemSettings.desktop.animation) $menu.style.animationDuration = `${itemSettings.duration}ms` desktopListeners() } } resizeDetection() // State Detection window.addEventListener('resize', () => { resizeDetection() }) } addToCollection(item, options, id) { this.collection.push({ $el: item, id: id || null, options: objectAssignDeep( {}, defaults, item.hasAttribute(dataAttributeName) ? JSON.parse(item.getAttribute(dataAttributeName)) : {}, options, ), }); } getItems() { const that = this; let newCollection = []; for (let i = 0; i < that.collection.length; i += 1) { newCollection.push(that.collection[i].$initializedEl); } return newCollection; } getItem(ind) { return this.collection[ind].$initializedEl; } }
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: server1.winmanyltd.com
Server IP: 203.161.60.52
PHP Version: 8.3.27
Server Software: Apache
System: Linux server1.winmanyltd.com 4.18.0-553.22.1.el8_10.x86_64 #1 SMP Tue Sep 24 05:16:59 EDT 2024 x86_64
HDD Total: 117.98 GB
HDD Free: 59.81 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
Yes
pkexec:
Yes
git:
Yes
User Info
Username: eliosofonline
User ID (UID): 1002
Group ID (GID): 1003
Script Owner UID: 1002
Current Dir Owner: 1002