diff --git a/amd/build/smartmenu.min.js b/amd/build/smartmenu.min.js index 6eca61394f2..f7a25da1bd8 100644 --- a/amd/build/smartmenu.min.js +++ b/amd/build/smartmenu.min.js @@ -5,6 +5,6 @@ * @copyright 2023 bdecent GmbH * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("theme_boost_union/smartmenu",["jquery","core/moremenu"],(function($){const hideSubmenus=target=>{var visibleMenu=document.querySelectorAll("nav.moremenu .dropdown-submenu.show");null!==visibleMenu&&visibleMenu.forEach((el=>{el!=target&&el.classList.remove("show")}))},moveOutMoreMenu=navMenu=>{if(null!==navMenu){var outMenus=navMenu.querySelectorAll(".dropdownmoremenu .force-menu-out"),menuslist=[];if(null!==outMenus){outMenus.forEach((menu=>{menu.querySelector("a").classList.remove("dropdown-item"),menu.querySelector("a").classList.add("nav-link"),menuslist.push(menu),menu.parentNode.removeChild(menu)}));var length=menuslist.length,newPosition=navMenu.children.length-1-length||0;menuslist.forEach((menu=>navMenu.insertBefore(menu,navMenu.children[newPosition]))),window.dispatchEvent(new Event("resize"))}}};return{init:()=>{(()=>{var submenu=document.querySelectorAll("nav.moremenu .dropdown-submenu");null!==submenu&&submenu.forEach((item=>{item.addEventListener("click",(e=>{var target=e.currentTarget;hideSubmenus(target),target.classList.toggle("show"),e.stopPropagation()}))})),$(document).on("hidden.bs.dropdown",(e=>{var submenus=e.relatedTarget.parentNode.querySelectorAll(".dropdown-submenu.show");null!==submenus&&submenus.forEach((e=>e.classList.remove("show")))})),document.addEventListener("click",(e=>{var dropdown=e.target.closest(".dropdownmoremenu"),subMenu=e.target.closest(".dropdown-submenu");dropdown&&null!==subMenu&&(dropdown.querySelectorAll(".dropdown-submenu.show").forEach((menu=>{menu.classList.remove("show")})),subMenu.classList.toggle("show"));var dropdownMenu=e.target.parentNode.classList.contains("dropdown");dropdown&&dropdownMenu&&dropdown.querySelectorAll(".dropdown-menu.show").forEach((menu=>{menu!=e.target.closest(".dropdown-menu")&&menu.classList.remove("show")}))}),!0);var helpIcon=document.querySelectorAll(".moremenu .dropdown .menu-helpicon");null!==helpIcon&&helpIcon.forEach((icon=>{icon.addEventListener("click",(e=>{e.stopPropagation()}))}))})(),(()=>{var cards=document.querySelectorAll(".card-dropdown.card-overflow-no-wrap");if(null!==cards){var scrollStart,scrollMoved;let startPos,scrollPos;cards.forEach((card=>{var scrollElement=card.querySelector(".dropdown-menu");scrollElement.addEventListener("mousedown",(e=>{scrollStart=!0;var target=e.currentTarget.querySelector(".card-block-wrapper");startPos=e.pageX,scrollPos=target.scrollLeft})),scrollElement.addEventListener("mousemove",(e=>{if(e.preventDefault(),!scrollStart)return;scrollMoved=!0;var target=e.currentTarget.querySelector(".card-block-wrapper");const scroll=e.pageX-startPos;target.scrollLeft=scrollPos-scroll})),scrollElement.addEventListener("click",(e=>{scrollMoved&&(e.preventDefault(),scrollMoved=!1),e.stopPropagation()})),scrollElement.addEventListener("mouseleave",(()=>{scrollStart=!1,scrollMoved=!1})),scrollElement.addEventListener("mouseup",(()=>{scrollStart=!1}))}))}})(),(()=>{var primaryNav=document.querySelector(".primary-navigation ul.more-nav");moveOutMoreMenu(primaryNav);var menuBar=document.querySelector("nav.menubar ul.more-nav");moveOutMoreMenu(menuBar)})()}}})); +define("theme_boost_union/smartmenu",["jquery","core/moremenu"],(function($){const Selectors_dropDownMenu="dropdownmoremenu",Selectors_forceOut="force-menu-out",Selectors_navLink="nav-link",Selectors_dropDownItem="dropdown-item",Selectors_classes={dropDownMenuList:".dropdownmoremenu ul.dropdown-menu",forceOut:".dropdownmoremenu .force-menu-out"},hideSubmenus=target=>{var visibleMenu=document.querySelectorAll("nav.moremenu .dropdown-submenu.show");null!==visibleMenu&&visibleMenu.forEach((el=>{el!=target&&el.classList.remove("show")}))},setOutMenuPositions=navMenu=>{if(null!=navMenu){var li=Array.from(navMenu.children).filter((e=>!e.classList.contains(Selectors_dropDownMenu))),position=0;li.forEach((menu=>{position=li.indexOf(menu),menu.dataset.orgposition=position}));var moreMenu=navMenu.querySelector(Selectors_classes.dropDownMenuList);Array.from(moreMenu.children).forEach((menu=>{menu.dataset.orgposition=position++}))}},moveOutMoreMenu=navMenu=>{if(null!==navMenu){var li=Array.from(navMenu.children).reverse().filter((e=>!e.classList.contains(Selectors_forceOut)&&!e.classList.contains(Selectors_dropDownMenu)));if(!(li.length<1)){var outMenus=navMenu.querySelectorAll(Selectors_classes.forceOut),menuslist=[];if(null!==outMenus){outMenus.forEach((menu=>{menu.querySelector("a").classList.remove(Selectors_dropDownItem),menu.querySelector("a").classList.add(Selectors_navLink),menuslist.push(menu),menu.parentNode.removeChild(menu)}));var moveMenus=[];menuslist.forEach((menu=>{navMenu.insertBefore(menu,navMenu.lastElementChild)&&li.length>0&&moveMenus.push(li.shift())})),moveMenus.forEach((menu=>{navMenu.insertBefore(menu,navMenu.lastElementChild)})),window.dispatchEvent(new Event("resize")),(navMenu=>{Array.from(navMenu.children).sort(((a,b)=>a.dataset.orgposition-b.dataset.orgposition)).forEach((menu=>navMenu.appendChild(menu)))})(navMenu)}}}};return{init:()=>{(()=>{var submenu=document.querySelectorAll("nav.moremenu .dropdown-submenu");null!==submenu&&submenu.forEach((item=>{item.addEventListener("click",(e=>{var target=e.currentTarget;hideSubmenus(target),target.classList.toggle("show"),e.stopPropagation()}))})),$(document).on("hidden.bs.dropdown",(e=>{var submenus=e.relatedTarget.parentNode.querySelectorAll(".dropdown-submenu.show");null!==submenus&&submenus.forEach((e=>e.classList.remove("show")))})),document.addEventListener("click",(e=>{var dropdown=e.target.closest(".dropdownmoremenu"),subMenu=e.target.closest(".dropdown-submenu");dropdown&&null!==subMenu&&(dropdown.querySelectorAll(".dropdown-submenu.show").forEach((menu=>{menu.classList.remove("show")})),subMenu.classList.toggle("show"));var dropdownMenu=e.target.parentNode.classList.contains("dropdown");dropdown&&dropdownMenu&&dropdown.querySelectorAll(".dropdown-menu.show").forEach((menu=>{menu!=e.target.closest(".dropdown-menu")&&menu.classList.remove("show")}))}),!0);var helpIcon=document.querySelectorAll(".moremenu .dropdown .menu-helpicon");null!==helpIcon&&helpIcon.forEach((icon=>{icon.addEventListener("click",(e=>{e.stopPropagation()}))}))})(),(()=>{var cards=document.querySelectorAll(".card-dropdown.card-overflow-no-wrap");if(null!==cards){var scrollStart,scrollMoved;let startPos,scrollPos;cards.forEach((card=>{var scrollElement=card.querySelector(".dropdown-menu");scrollElement.addEventListener("mousedown",(e=>{scrollStart=!0;var target=e.currentTarget.querySelector(".card-block-wrapper");startPos=e.pageX,scrollPos=target.scrollLeft})),scrollElement.addEventListener("mousemove",(e=>{if(e.preventDefault(),!scrollStart)return;scrollMoved=!0;var target=e.currentTarget.querySelector(".card-block-wrapper");const scroll=e.pageX-startPos;target.scrollLeft=scrollPos-scroll})),scrollElement.addEventListener("click",(e=>{scrollMoved&&(e.preventDefault(),scrollMoved=!1),e.stopPropagation()})),scrollElement.addEventListener("mouseleave",(()=>{scrollStart=!1,scrollMoved=!1})),scrollElement.addEventListener("mouseup",(()=>{scrollStart=!1}))}))}})(),(()=>{var primaryNav=document.querySelector(".primary-navigation ul.more-nav");null!=primaryNav&&(setOutMenuPositions(primaryNav),moveOutMoreMenu(primaryNav));var menuBar=document.querySelector("nav.menubar ul.more-nav");null!=menuBar&&(setOutMenuPositions(menuBar),moveOutMoreMenu(menuBar)),window.onresize=e=>{e.isTrusted&&(moveOutMoreMenu(primaryNav),moveOutMoreMenu(menuBar))}})()}}})); //# sourceMappingURL=smartmenu.min.js.map \ No newline at end of file diff --git a/amd/build/smartmenu.min.js.map b/amd/build/smartmenu.min.js.map index 6877d2a276f..ae4d37c9fdb 100644 --- a/amd/build/smartmenu.min.js.map +++ b/amd/build/smartmenu.min.js.map @@ -1 +1 @@ -{"version":3,"file":"smartmenu.min.js","sources":["../src/smartmenu.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 .\n\n/**\n * Theme Boost Union - JS for smart menu to realize the third level submenu support.\n *\n * @module theme_boost_union/smartmenu\n * @copyright 2023 bdecent GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine([\"jquery\", \"core/moremenu\"], function($) {\n /**\n * Implement the second level of submenu support.\n * Find the submenus inside the dropdown, add an event listener for click event which - on the click - shows the submenu list.\n */\n const addSubmenu = () => {\n // Fetch the list of submenus from moremenu.\n var submenu = document.querySelectorAll('nav.moremenu .dropdown-submenu');\n if (submenu !== null) {\n submenu.forEach((item) => {\n // Add event listener to show the submenu on click.\n item.addEventListener('click', (e) => {\n var target = e.currentTarget;\n // Hide the shown menu.\n hideSubmenus(target);\n target.classList.toggle('show');\n // Prevent hiding the parent menu.\n e.stopPropagation();\n });\n });\n }\n\n // Hide the submenus when its parent dropdown is hidden.\n $(document).on('hidden.bs.dropdown', e => {\n var target = e.relatedTarget.parentNode;\n var submenus = target.querySelectorAll('.dropdown-submenu.show');\n if (submenus !== null) {\n submenus.forEach((e) => e.classList.remove('show'));\n }\n });\n\n // Provide the third level menu support inside the more menu.\n // StopPropagation used in the toggledropdown method on Moremenu.js, It prevents the opening of the third level menus.\n // Used the document delegation method to fetch the click on moremenu and submenu.\n document.addEventListener('click', (e) => {\n var dropdown = e.target.closest('.dropdownmoremenu');\n var subMenu = e.target.closest('.dropdown-submenu');\n if (dropdown && subMenu !== null) {\n // Hide the previously opend submenus. before open the new one.\n dropdown.querySelectorAll('.dropdown-submenu.show').forEach((menu) => {\n menu.classList.remove('show');\n });\n subMenu.classList.toggle('show');\n }\n\n // Hide the opened menus before open the other menus.\n var dropdownMenu = e.target.parentNode.classList.contains('dropdown');\n if (dropdown && dropdownMenu) {\n dropdown.querySelectorAll('.dropdown-menu.show').forEach((menu) => {\n // Hide the opened menus in more menu.\n if (menu != e.target.closest('.dropdown-menu')) {\n menu.classList.remove('show');\n }\n });\n }\n\n }, true);\n\n // Prevent the closing of dropdown during the click on help icon.\n var helpIcon = document.querySelectorAll('.moremenu .dropdown .menu-helpicon');\n if (helpIcon !== null) {\n helpIcon.forEach((icon) => {\n icon.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n });\n }\n };\n\n /**\n * Hide visible submenus before display new submenu.\n *\n * @param {Selector} target\n */\n const hideSubmenus = (target) => {\n var visibleMenu = document.querySelectorAll('nav.moremenu .dropdown-submenu.show');\n if (visibleMenu !== null) {\n visibleMenu.forEach((el) => {\n if (el != target) {\n el.classList.remove('show');\n }\n });\n }\n };\n\n /**\n * Make the no wrapped card menus scroll using swipe or drag.\n */\n const cardScroll = () => {\n var cards = document.querySelectorAll('.card-dropdown.card-overflow-no-wrap');\n if (cards !== null) {\n var scrollStart; // Verify the mouse is clicked and still in click not released.\n var scrollMoved; // Prevent the click on scrolling.\n let startPos, scrollPos;\n\n cards.forEach((card) => {\n var scrollElement = card.querySelector('.dropdown-menu');\n\n scrollElement.addEventListener('mousedown', (e) => {\n scrollStart = true;\n var target = e.currentTarget.querySelector('.card-block-wrapper');\n startPos = e.pageX;\n scrollPos = target.scrollLeft;\n });\n\n scrollElement.addEventListener('mousemove', (e) => {\n e.preventDefault();\n if (!scrollStart) {\n return;\n }\n scrollMoved = true;\n var target = e.currentTarget.querySelector('.card-block-wrapper');\n const scroll = e.pageX - startPos;\n target.scrollLeft = scrollPos - scroll;\n });\n\n scrollElement.addEventListener('click', (e) => {\n if (scrollMoved) {\n e.preventDefault();\n scrollMoved = false;\n }\n e.stopPropagation();\n });\n scrollElement.addEventListener('mouseleave', () => {\n scrollStart = false;\n scrollMoved = false;\n });\n scrollElement.addEventListener('mouseup', () => {\n scrollStart = false;\n });\n });\n }\n };\n\n /**\n * Move the menubar and primary navigation menu items from more menu.\n */\n const autoCollapse = () => {\n var primaryNav = document.querySelector('.primary-navigation ul.more-nav');\n moveOutMoreMenu(primaryNav);\n\n var menuBar = document.querySelector('nav.menubar ul.more-nav');\n moveOutMoreMenu(menuBar);\n };\n\n /**\n * Move the items from more menu, items which is set to force outside more menu.\n * Remove those items from more menu and insert the menu before the last normal item.\n * Find the length and children's length to insert the out menus in that positions.\n * Rerun the more menu it will more the other normal menus into more menu to fix the alignmenu issue.\n *\n * @param {HTMLElement} navMenu The navbar container.\n */\n const moveOutMoreMenu = (navMenu) => {\n\n if (navMenu === null) {\n return;\n }\n\n var outMenus = navMenu.querySelectorAll('.dropdownmoremenu .force-menu-out');\n var menuslist = [];\n\n if (outMenus === null) {\n return;\n }\n\n outMenus.forEach((menu) => {\n menu.querySelector('a').classList.remove('dropdown-item');\n menu.querySelector('a').classList.add('nav-link');\n\n menuslist.push(menu);\n menu.parentNode.removeChild(menu);\n });\n // Find the length and children's length to insert the out menus in that positions.\n var length = menuslist.length;\n var navLength = navMenu.children.length - 1; // Remove more menu.\n var newPosition = navLength - length || 0;\n // Insert the stored menus before the more menu.\n menuslist.forEach((menu) => navMenu.insertBefore(menu, navMenu.children[newPosition]));\n window.dispatchEvent(new Event('resize')); // Dispatch the resize event to create more menu.\n };\n\n return {\n init: () => {\n addSubmenu();\n cardScroll();\n autoCollapse();\n }\n };\n});\n"],"names":["define","$","hideSubmenus","target","visibleMenu","document","querySelectorAll","forEach","el","classList","remove","moveOutMoreMenu","navMenu","outMenus","menuslist","menu","querySelector","add","push","parentNode","removeChild","length","newPosition","children","insertBefore","window","dispatchEvent","Event","init","submenu","item","addEventListener","e","currentTarget","toggle","stopPropagation","on","submenus","relatedTarget","dropdown","closest","subMenu","dropdownMenu","contains","helpIcon","icon","addSubmenu","cards","scrollStart","scrollMoved","startPos","scrollPos","card","scrollElement","pageX","scrollLeft","preventDefault","scroll","cardScroll","primaryNav","menuBar","autoCollapse"],"mappings":";;;;;;;AAuBAA,qCAAO,CAAC,SAAU,kBAAkB,SAASC,SA0EnCC,aAAgBC,aACdC,YAAcC,SAASC,iBAAiB,uCACxB,OAAhBF,aACAA,YAAYG,SAASC,KACbA,IAAML,QACNK,GAAGC,UAAUC,OAAO,YA0E9BC,gBAAmBC,aAEL,OAAZA,aAIAC,SAAWD,QAAQN,iBAAiB,qCACpCQ,UAAY,MAEC,OAAbD,UAIJA,SAASN,SAASQ,OACdA,KAAKC,cAAc,KAAKP,UAAUC,OAAO,iBACzCK,KAAKC,cAAc,KAAKP,UAAUQ,IAAI,YAEtCH,UAAUI,KAAKH,MACfA,KAAKI,WAAWC,YAAYL,aAG5BM,OAASP,UAAUO,OAEnBC,YADYV,QAAQW,SAASF,OAAS,EACZA,QAAU,EAExCP,UAAUP,SAASQ,MAASH,QAAQY,aAAaT,KAAMH,QAAQW,SAASD,gBACxEG,OAAOC,cAAc,IAAIC,MAAM,oBAG5B,CACHC,KAAM,KAlLS,UAEXC,QAAUxB,SAASC,iBAAiB,kCACxB,OAAZuB,SACAA,QAAQtB,SAASuB,OAEbA,KAAKC,iBAAiB,SAAUC,QACxB7B,OAAS6B,EAAEC,cAEf/B,aAAaC,QACbA,OAAOM,UAAUyB,OAAO,QAExBF,EAAEG,wBAMdlC,EAAEI,UAAU+B,GAAG,sBAAsBJ,QAE7BK,SADSL,EAAEM,cAAcnB,WACPb,iBAAiB,0BACtB,OAAb+B,UACAA,SAAS9B,SAASyB,GAAMA,EAAEvB,UAAUC,OAAO,aAOnDL,SAAS0B,iBAAiB,SAAUC,QAC5BO,SAAWP,EAAE7B,OAAOqC,QAAQ,qBAC5BC,QAAUT,EAAE7B,OAAOqC,QAAQ,qBAC3BD,UAAwB,OAAZE,UAEZF,SAASjC,iBAAiB,0BAA0BC,SAASQ,OACzDA,KAAKN,UAAUC,OAAO,WAE1B+B,QAAQhC,UAAUyB,OAAO,aAIzBQ,aAAeV,EAAE7B,OAAOgB,WAAWV,UAAUkC,SAAS,YACtDJ,UAAYG,cACZH,SAASjC,iBAAiB,uBAAuBC,SAASQ,OAElDA,MAAQiB,EAAE7B,OAAOqC,QAAQ,mBACzBzB,KAAKN,UAAUC,OAAO,cAKnC,OAGCkC,SAAWvC,SAASC,iBAAiB,sCACxB,OAAbsC,UACAA,SAASrC,SAASsC,OACdA,KAAKd,iBAAiB,SAAUC,IAC5BA,EAAEG,yBAyHVW,GAhGW,UACXC,MAAQ1C,SAASC,iBAAiB,2CACxB,OAAVyC,MAAgB,KACZC,YACAC,gBACAC,SAAUC,UAEdJ,MAAMxC,SAAS6C,WACPC,cAAgBD,KAAKpC,cAAc,kBAEvCqC,cAActB,iBAAiB,aAAcC,IACzCgB,aAAc,MACV7C,OAAS6B,EAAEC,cAAcjB,cAAc,uBAC3CkC,SAAWlB,EAAEsB,MACbH,UAAYhD,OAAOoD,cAGvBF,cAActB,iBAAiB,aAAcC,OACzCA,EAAEwB,kBACGR,mBAGLC,aAAc,MACV9C,OAAS6B,EAAEC,cAAcjB,cAAc,6BACrCyC,OAASzB,EAAEsB,MAAQJ,SACzB/C,OAAOoD,WAAaJ,UAAYM,UAGpCJ,cAActB,iBAAiB,SAAUC,IACjCiB,cACAjB,EAAEwB,iBACFP,aAAc,GAElBjB,EAAEG,qBAENkB,cAActB,iBAAiB,cAAc,KACzCiB,aAAc,EACdC,aAAc,KAElBI,cAActB,iBAAiB,WAAW,KACtCiB,aAAc,UAyDtBU,GAhDa,UACbC,WAAatD,SAASW,cAAc,mCACxCL,gBAAgBgD,gBAEZC,QAAUvD,SAASW,cAAc,2BACrCL,gBAAgBiD,UA4CZC"} \ No newline at end of file +{"version":3,"file":"smartmenu.min.js","sources":["../src/smartmenu.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 .\n\n/**\n * Theme Boost Union - JS for smart menu to realize the third level submenu support.\n *\n * @module theme_boost_union/smartmenu\n * @copyright 2023 bdecent GmbH \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine([\"jquery\", \"core/moremenu\"], function($) {\n\n const Selectors = {\n dropDownMenu: \"dropdownmoremenu\",\n forceOut: \"force-menu-out\",\n navLink: \"nav-link\",\n dropDownItem: \"dropdown-item\",\n classes: {\n dropDownMenuList: \".dropdownmoremenu ul.dropdown-menu\",\n forceOut: \".dropdownmoremenu .force-menu-out\"\n }\n };\n\n /**\n * Implement the second level of submenu support.\n * Find the submenus inside the dropdown, add an event listener for click event which - on the click - shows the submenu list.\n */\n const addSubmenu = () => {\n // Fetch the list of submenus from moremenu.\n var submenu = document.querySelectorAll('nav.moremenu .dropdown-submenu');\n if (submenu !== null) {\n submenu.forEach((item) => {\n // Add event listener to show the submenu on click.\n item.addEventListener('click', (e) => {\n var target = e.currentTarget;\n // Hide the shown menu.\n hideSubmenus(target);\n target.classList.toggle('show');\n // Prevent hiding the parent menu.\n e.stopPropagation();\n });\n });\n }\n\n // Hide the submenus when its parent dropdown is hidden.\n $(document).on('hidden.bs.dropdown', e => {\n var target = e.relatedTarget.parentNode;\n var submenus = target.querySelectorAll('.dropdown-submenu.show');\n if (submenus !== null) {\n submenus.forEach((e) => e.classList.remove('show'));\n }\n });\n\n // Provide the third level menu support inside the more menu.\n // StopPropagation used in the toggledropdown method on Moremenu.js, It prevents the opening of the third level menus.\n // Used the document delegation method to fetch the click on moremenu and submenu.\n document.addEventListener('click', (e) => {\n var dropdown = e.target.closest('.dropdownmoremenu');\n var subMenu = e.target.closest('.dropdown-submenu');\n if (dropdown && subMenu !== null) {\n // Hide the previously opend submenus. before open the new one.\n dropdown.querySelectorAll('.dropdown-submenu.show').forEach((menu) => {\n menu.classList.remove('show');\n });\n subMenu.classList.toggle('show');\n }\n\n // Hide the opened menus before open the other menus.\n var dropdownMenu = e.target.parentNode.classList.contains('dropdown');\n if (dropdown && dropdownMenu) {\n dropdown.querySelectorAll('.dropdown-menu.show').forEach((menu) => {\n // Hide the opened menus in more menu.\n if (menu != e.target.closest('.dropdown-menu')) {\n menu.classList.remove('show');\n }\n });\n }\n\n }, true);\n\n // Prevent the closing of dropdown during the click on help icon.\n var helpIcon = document.querySelectorAll('.moremenu .dropdown .menu-helpicon');\n if (helpIcon !== null) {\n helpIcon.forEach((icon) => {\n icon.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n });\n }\n };\n\n /**\n * Hide visible submenus before display new submenu.\n *\n * @param {Selector} target\n */\n const hideSubmenus = (target) => {\n var visibleMenu = document.querySelectorAll('nav.moremenu .dropdown-submenu.show');\n if (visibleMenu !== null) {\n visibleMenu.forEach((el) => {\n if (el != target) {\n el.classList.remove('show');\n }\n });\n }\n };\n\n /**\n * Make the no wrapped card menus scroll using swipe or drag.\n */\n const cardScroll = () => {\n var cards = document.querySelectorAll('.card-dropdown.card-overflow-no-wrap');\n if (cards !== null) {\n var scrollStart; // Verify the mouse is clicked and still in click not released.\n var scrollMoved; // Prevent the click on scrolling.\n let startPos, scrollPos;\n\n cards.forEach((card) => {\n var scrollElement = card.querySelector('.dropdown-menu');\n\n scrollElement.addEventListener('mousedown', (e) => {\n scrollStart = true;\n var target = e.currentTarget.querySelector('.card-block-wrapper');\n startPos = e.pageX;\n scrollPos = target.scrollLeft;\n });\n\n scrollElement.addEventListener('mousemove', (e) => {\n e.preventDefault();\n if (!scrollStart) {\n return;\n }\n scrollMoved = true;\n var target = e.currentTarget.querySelector('.card-block-wrapper');\n const scroll = e.pageX - startPos;\n target.scrollLeft = scrollPos - scroll;\n });\n\n scrollElement.addEventListener('click', (e) => {\n if (scrollMoved) {\n e.preventDefault();\n scrollMoved = false;\n }\n e.stopPropagation();\n });\n scrollElement.addEventListener('mouseleave', () => {\n scrollStart = false;\n scrollMoved = false;\n });\n scrollElement.addEventListener('mouseup', () => {\n scrollStart = false;\n });\n });\n }\n };\n\n /**\n * Move the menubar and primary navigation menu items from more menu.\n */\n const autoCollapse = () => {\n var primaryNav = document.querySelector('.primary-navigation ul.more-nav');\n if (primaryNav != undefined) {\n setOutMenuPositions(primaryNav); // Create a data flag to maintain the original position of the menus.\n moveOutMoreMenu(primaryNav);\n }\n\n\n var menuBar = document.querySelector('nav.menubar ul.more-nav');\n if (menuBar != undefined) {\n setOutMenuPositions(menuBar);\n moveOutMoreMenu(menuBar);\n }\n\n window.onresize = (e) => {\n // Verify the event is original by browser resize.\n if (e.isTrusted) {\n moveOutMoreMenu(primaryNav);\n moveOutMoreMenu(menuBar);\n }\n };\n };\n\n /**\n * Finds and sets the positions of all menus before moving them,\n * helping to maintain the positions of the menus after being moved out from the moremenu.\n *\n * @param {HTMLElement} navMenu The navbar container.\n */\n const setOutMenuPositions = (navMenu) => {\n\n if (navMenu === undefined || navMenu === null) {\n return;\n }\n\n // Find all menu items excluding the dropdownmoremenu class.\n var li = Array.from(navMenu.children).filter((e) => !e.classList.contains(Selectors.dropDownMenu));\n\n // Initialize the position variable.\n var position = 0;\n\n // Loop through each menu item and set its original position.\n li.forEach((menu) => {\n position = li.indexOf(menu);\n menu.dataset.orgposition = position; // Store the original position in the menu's dataset.\n });\n\n // Maintain the positions of the menus inside the moremenu from the last position of the outside menus.\n var moreMenu = navMenu.querySelector(Selectors.classes.dropDownMenuList);\n Array.from(moreMenu.children).forEach((menu) => {\n menu.dataset.orgposition = position++;\n });\n };\n\n /**\n * Rearranges the menus placed outside the more menu based on their original positions.\n *\n * @param {HTMLElement} navMenu The navbar container.\n */\n const reArrangeMenuOrgPositions = (navMenu) => {\n // Retrieve all menu items and sort them based on their original positions.\n var li = Array.from(navMenu.children).sort((a, b) => a.dataset.orgposition - b.dataset.orgposition);\n // Append the sorted menu items back to the navbar container.\n li.forEach((menu) => navMenu.appendChild(menu));\n };\n\n /**\n * Move the items from more menu, items which is set to force outside more menu.\n * Remove those items from more menu and insert the menu before the last normal item.\n * Find the length and children's length to insert the out menus in that positions.\n * Move the non forced more menu to moremenu to make the menu alignment.\n * Rerun the more menu it will more the other normal menus into more menu to fix the alignmenu issue.\n * After the menus are move out, rearrange menus to its original positions.\n *\n * @param {HTMLElement} navMenu The navbar container.\n */\n const moveOutMoreMenu = (navMenu) => {\n\n if (navMenu === null) {\n return;\n }\n\n // Filter the available menus to move inside of more menu.\n var li = Array.from(navMenu.children).reverse().filter(\n (e) => !e.classList.contains(Selectors.forceOut) && !e.classList.contains(Selectors.dropDownMenu));\n\n // Alternate menus are not available for move to moremenu, stop make the menus move to outside.\n if (li.length < 1) {\n return;\n }\n\n var outMenus = navMenu.querySelectorAll(Selectors.classes.forceOut);\n var menuslist = [];\n\n if (outMenus === null) {\n return;\n }\n\n outMenus.forEach((menu) => {\n menu.querySelector('a').classList.remove(Selectors.dropDownItem);\n menu.querySelector('a').classList.add(Selectors.navLink);\n\n menuslist.push(menu);\n menu.parentNode.removeChild(menu);\n });\n\n // Insert the stored menus before the more menu.\n var moveMenus = [];\n menuslist.forEach((menu) => {\n if (navMenu.insertBefore(menu, navMenu.lastElementChild) && li.length > 0) {\n // Instead of move into moremenu, place the menus before the moremenu will moved to moremenu by moremenu.js.\n moveMenus.push(li.shift());\n }\n });\n\n // Move the non forced more menu before the moremenu to make the menu alignment.\n moveMenus.forEach((menu) => {\n navMenu.insertBefore(menu, navMenu.lastElementChild);\n });\n\n window.dispatchEvent(new Event('resize')); // Dispatch the resize event to create more menu.\n\n // After the menus are move out, rearrange menus to its original positions.\n reArrangeMenuOrgPositions(navMenu);\n };\n\n return {\n init: () => {\n addSubmenu();\n cardScroll();\n autoCollapse();\n }\n };\n});\n"],"names":["define","$","Selectors","dropDownMenuList","forceOut","hideSubmenus","target","visibleMenu","document","querySelectorAll","forEach","el","classList","remove","setOutMenuPositions","navMenu","li","Array","from","children","filter","e","contains","position","menu","indexOf","dataset","orgposition","moreMenu","querySelector","moveOutMoreMenu","reverse","length","outMenus","menuslist","add","push","parentNode","removeChild","moveMenus","insertBefore","lastElementChild","shift","window","dispatchEvent","Event","sort","a","b","appendChild","reArrangeMenuOrgPositions","init","submenu","item","addEventListener","currentTarget","toggle","stopPropagation","on","submenus","relatedTarget","dropdown","closest","subMenu","dropdownMenu","helpIcon","icon","addSubmenu","cards","scrollStart","scrollMoved","startPos","scrollPos","card","scrollElement","pageX","scrollLeft","preventDefault","scroll","cardScroll","primaryNav","undefined","menuBar","onresize","isTrusted","autoCollapse"],"mappings":"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"} \ No newline at end of file diff --git a/amd/src/smartmenu.js b/amd/src/smartmenu.js index 892b105dc9b..3c1489ffe65 100644 --- a/amd/src/smartmenu.js +++ b/amd/src/smartmenu.js @@ -22,6 +22,18 @@ */ define(["jquery", "core/moremenu"], function($) { + + const Selectors = { + dropDownMenu: "dropdownmoremenu", + forceOut: "force-menu-out", + navLink: "nav-link", + dropDownItem: "dropdown-item", + classes: { + dropDownMenuList: ".dropdownmoremenu ul.dropdown-menu", + forceOut: ".dropdownmoremenu .force-menu-out" + } + }; + /** * Implement the second level of submenu support. * Find the submenus inside the dropdown, add an event listener for click event which - on the click - shows the submenu list. @@ -160,17 +172,77 @@ define(["jquery", "core/moremenu"], function($) { */ const autoCollapse = () => { var primaryNav = document.querySelector('.primary-navigation ul.more-nav'); - moveOutMoreMenu(primaryNav); + if (primaryNav != undefined) { + setOutMenuPositions(primaryNav); // Create a data flag to maintain the original position of the menus. + moveOutMoreMenu(primaryNav); + } + var menuBar = document.querySelector('nav.menubar ul.more-nav'); - moveOutMoreMenu(menuBar); + if (menuBar != undefined) { + setOutMenuPositions(menuBar); + moveOutMoreMenu(menuBar); + } + + window.onresize = (e) => { + // Verify the event is original by browser resize. + if (e.isTrusted) { + moveOutMoreMenu(primaryNav); + moveOutMoreMenu(menuBar); + } + }; + }; + + /** + * Finds and sets the positions of all menus before moving them, + * helping to maintain the positions of the menus after being moved out from the moremenu. + * + * @param {HTMLElement} navMenu The navbar container. + */ + const setOutMenuPositions = (navMenu) => { + + if (navMenu === undefined || navMenu === null) { + return; + } + + // Find all menu items excluding the dropdownmoremenu class. + var li = Array.from(navMenu.children).filter((e) => !e.classList.contains(Selectors.dropDownMenu)); + + // Initialize the position variable. + var position = 0; + + // Loop through each menu item and set its original position. + li.forEach((menu) => { + position = li.indexOf(menu); + menu.dataset.orgposition = position; // Store the original position in the menu's dataset. + }); + + // Maintain the positions of the menus inside the moremenu from the last position of the outside menus. + var moreMenu = navMenu.querySelector(Selectors.classes.dropDownMenuList); + Array.from(moreMenu.children).forEach((menu) => { + menu.dataset.orgposition = position++; + }); + }; + + /** + * Rearranges the menus placed outside the more menu based on their original positions. + * + * @param {HTMLElement} navMenu The navbar container. + */ + const reArrangeMenuOrgPositions = (navMenu) => { + // Retrieve all menu items and sort them based on their original positions. + var li = Array.from(navMenu.children).sort((a, b) => a.dataset.orgposition - b.dataset.orgposition); + // Append the sorted menu items back to the navbar container. + li.forEach((menu) => navMenu.appendChild(menu)); }; /** * Move the items from more menu, items which is set to force outside more menu. * Remove those items from more menu and insert the menu before the last normal item. * Find the length and children's length to insert the out menus in that positions. + * Move the non forced more menu to moremenu to make the menu alignment. * Rerun the more menu it will more the other normal menus into more menu to fix the alignmenu issue. + * After the menus are move out, rearrange menus to its original positions. * * @param {HTMLElement} navMenu The navbar container. */ @@ -180,7 +252,16 @@ define(["jquery", "core/moremenu"], function($) { return; } - var outMenus = navMenu.querySelectorAll('.dropdownmoremenu .force-menu-out'); + // Filter the available menus to move inside of more menu. + var li = Array.from(navMenu.children).reverse().filter( + (e) => !e.classList.contains(Selectors.forceOut) && !e.classList.contains(Selectors.dropDownMenu)); + + // Alternate menus are not available for move to moremenu, stop make the menus move to outside. + if (li.length < 1) { + return; + } + + var outMenus = navMenu.querySelectorAll(Selectors.classes.forceOut); var menuslist = []; if (outMenus === null) { @@ -188,19 +269,31 @@ define(["jquery", "core/moremenu"], function($) { } outMenus.forEach((menu) => { - menu.querySelector('a').classList.remove('dropdown-item'); - menu.querySelector('a').classList.add('nav-link'); + menu.querySelector('a').classList.remove(Selectors.dropDownItem); + menu.querySelector('a').classList.add(Selectors.navLink); menuslist.push(menu); menu.parentNode.removeChild(menu); }); - // Find the length and children's length to insert the out menus in that positions. - var length = menuslist.length; - var navLength = navMenu.children.length - 1; // Remove more menu. - var newPosition = navLength - length || 0; + // Insert the stored menus before the more menu. - menuslist.forEach((menu) => navMenu.insertBefore(menu, navMenu.children[newPosition])); + var moveMenus = []; + menuslist.forEach((menu) => { + if (navMenu.insertBefore(menu, navMenu.lastElementChild) && li.length > 0) { + // Instead of move into moremenu, place the menus before the moremenu will moved to moremenu by moremenu.js. + moveMenus.push(li.shift()); + } + }); + + // Move the non forced more menu before the moremenu to make the menu alignment. + moveMenus.forEach((menu) => { + navMenu.insertBefore(menu, navMenu.lastElementChild); + }); + window.dispatchEvent(new Event('resize')); // Dispatch the resize event to create more menu. + + // After the menus are move out, rearrange menus to its original positions. + reArrangeMenuOrgPositions(navMenu); }; return { diff --git a/templates/smartmenus-cardmenu-children.mustache b/templates/smartmenus-cardmenu-children.mustache index cbfd42bc969..eee721104e5 100644 --- a/templates/smartmenus-cardmenu-children.mustache +++ b/templates/smartmenus-cardmenu-children.mustache @@ -83,7 +83,7 @@ {{/haschildren}} {{^haschildren}} -