{"version":3,"file":"mega-menu.js","names":[],"sources":["../resources/modern-javascript/mega-menu.js"],"sourcesContent":["import { lock, unlock } from 'tua-body-scroll-lock';\nimport { delegate } from '@d3r/js-tools';\nimport { Viewport } from '@d3r/js-tools';\n\nconst primaryNavTransitionDuration = 200;\nconst secondaryNavTransitionDuration = 600;\n\nconst legacyBasketCountSelector = '.js-basket-count .header-action__count';\nconst menuBasketButtonSelector = '.menu-actions__button[href=\"/basket\"]';\nconst menuBasketCountSelector = '.menu-actions__count span';\nconst loginRedirectSelector = '.js-login-redirect';\n\n/**\n * Get the element that contains the active slide-out panel.\n */\nconst getTargetElement = () => document.querySelectorAll('[data-subheader-scroll]');\n\nconst getGroupContentContainers = (el) => {\n    const root = el || document;\n\n    return root.querySelectorAll('.navigation__sub-links, .navigation__callout')\n};\n\nconst getScrollableElements = () => {\n    return document.querySelectorAll('.navigation__section--active .navigation__group-container, .navigation__section:has(.navigation__group-list--active) .navigation__group-content-container');\n}\n\nlet locked = false;\n\n/**\n * Lock the viewport while the desktop nav is open.\n */\nconst lockViewport = () => {\n    if (!locked) {\n        lock(getTargetElement(), {});\n        locked = true;\n    }\n}\n\n/**\n * Unlock the viewport after the desktop nav closes.\n */\nconst unlockViewport = () => {\n    if (locked) {\n        unlock(getTargetElement(), {});\n        locked = false;\n    }\n}\n\nlet trackTimeout = null;\nconst trackActivate = () => {\n    if (window.dataLayer) {\n        if (trackTimeout) {\n            clearTimeout(trackTimeout);\n        }\n\n        trackTimeout = setTimeout(() => {\n            window.dataLayer.push({\n                'event': 'activateNavigation',\n            });\n        }, 100);\n    }\n}\n\nconst setPrimaryNav = (active) => {\n    const megaMenu = document.querySelector('.mega-menu');\n\n    setTimeout(() => {\n        if (active) {\n            megaMenu.dataset.primaryNavOpen = true;\n        } else {\n            delete megaMenu.dataset.primaryNavOpen;\n        }\n    }, primaryNavTransitionDuration);\n}\n\nconst setSecondaryNav = (active) => {\n    const megaMenu = document.querySelector('.mega-menu');\n\n    setTimeout(() => {\n        if (active) {\n            megaMenu.dataset.secondaryNavOpen = true;\n        } else {\n            delete megaMenu.dataset.secondaryNavOpen;\n        }\n    }, secondaryNavTransitionDuration);\n}\n\n/**\n * Check whether to lock or ulock the viewport.\n */\nconst manageViewport = (isActive) => {\n    const viewport = new Viewport(Soho.breakpoints);\n\n    if (!viewport.matches('nav-v3')) {\n        if (isActive) {\n            deactivateSearch();\n            lockViewport();\n            setPrimaryNav(true);\n            trackActivate();\n        } else {\n            clearGroupContent();\n            deactivateNavigationGroupList();\n            unlockViewport();\n            setPrimaryNav();\n        }\n    }\n}\n\nconst checkScrollPosition = () => {\n    const megaMenu = document.querySelector('.mega-menu');\n\n    if (window.scrollY === 0) {\n        megaMenu.dataset.position = 'static';\n    } else {\n        megaMenu.dataset.position = 'sticky';\n    }\n}\n\nconst deactivateSearch = () => {\n    if (window.search?.isActive()) {\n        search.deactivate();\n    }\n}\n\nconst getActiveNavigationGroupList = () => {\n    return document.querySelector('.navigation__group-list--active');\n}\n\nconst activateNavigationGroupList = (e) => {\n    const group = e.target.closest('.navigation__group');\n    const list = group.querySelector('.navigation__group-list--menu');\n\n    if (list) {\n        deactivateNavigationGroupList();\n        list.classList.add('navigation__group-list--active');\n        setSecondaryNav(true);\n    }\n\n    updateGroupContent(group);\n}\n\nconst deactivateNavigationGroupList = () => {\n    const list = getActiveNavigationGroupList();\n\n    if (list) {\n        list.classList.remove('navigation__group-list--active');\n        setSecondaryNav();\n    }\n}\n\nconst toggleNavigationGroupList = (e) => {\n    const group = e.target.closest('.navigation__group');\n    const list = group.querySelector('.navigation__group-list--menu');\n\n    if (list) {\n        if (list.classList.contains('navigation__group-list--active')) {\n            list.classList.remove('navigation__group-list--active');\n\n            clearGroupContent();\n            setSecondaryNav();\n        } else {\n            deactivateNavigationGroupList();\n            list.classList.add('navigation__group-list--active');\n\n            updateGroupContent(group);\n            setSecondaryNav(true);\n        }\n    }\n}\n\nconst clearGroupContent = () => {\n    getGroupContentContainers().forEach((container) => {\n        container.innerHTML = '';\n    });\n}\n\nconst updateGroupContent = (group) => {\n    const list = group.querySelector('.navigation__group-list--menu');\n    const callout = group.querySelector('.navigation-callout');\n\n    clearGroupContent();\n\n    getGroupContentContainers(group.closest('.navigation__section')).forEach((container) => {\n        if (container.classList.contains('navigation__callout')) {\n            if (callout) {\n                container.appendChild(callout.cloneNode(true));\n            }\n        } else if (container.classList.contains('navigation__sub-links')) {\n            if (list) {\n                container.appendChild(list.cloneNode(true));\n            }\n        }\n    });\n}\n\nconst activateFirstNavButton = () => {\n    const button = document.querySelector('[data-toggle-submenu]');\n    \n    if (button) {\n        button.click();\n    }\n}\n\n// Reset the width of each navigation button\nconst resetNavButtonWidths = () => {\n    document.querySelectorAll('.navigation__button').forEach((button) => {\n        button.style.width = null;\n    });\n}\n\n// Set the width of each navigation button so that it doesn't \"jump\" when the font weight changes\nconst updateNavButtonWidths = () => {\n    document.querySelectorAll('.navigation__button').forEach((button) => {\n        button.style.width = null;\n        button.style.width = `${button.offsetWidth + 4}px`;\n    });\n}\n\n/**\n * Read the initial basket count from its cookie.\n */\nconst getBasketCount = () => {\n    const match = document.cookie.match(/(?:^|;\\s*)basket_count=([^;]*)/);\n\n    return match ? decodeURIComponent(match[1]) : '';\n};\n\n/**\n * Add the basket count expected by the legacy quick-basket handler to the new menu.\n */\nconst getBasketCountElement = () => {\n    const legacyCount = document.querySelector(legacyBasketCountSelector);\n\n    if (legacyCount) {\n        return legacyCount;\n    }\n\n    const existingMenuCount = document.querySelector(menuBasketCountSelector);\n\n    if (existingMenuCount) {\n        return existingMenuCount;\n    }\n\n    const basketButton = document.querySelector(menuBasketButtonSelector);\n    const basketItem = basketButton?.closest('.menu-actions__item');\n\n    if (!basketItem) {\n        return null;\n    }\n\n    const countWrapper = document.createElement('span');\n    const count = document.createElement('span');\n    countWrapper.classList.add('menu-actions__count');\n    count.textContent = getBasketCount();\n    countWrapper.append(count);\n    basketItem.append(countWrapper);\n\n    return count;\n};\n\n/**\n * Point the global quick-basket instance at the count used by the active header.\n */\nconst connectQuickBasketCount = () => {\n    const count = getBasketCountElement();\n\n    if (window.quickBasket && count) {\n        window.quickBasket.$count = count;\n    }\n}\n\nconst observe = () => {\n    // We need to call this in this manner when the page is loaded and the scroll position is not 0\n    // Because the Soho notice/header arrangement is different to other sites if we don't include the timeout\n    // then it will remain static because the package code is firing after this code\n    setTimeout(checkScrollPosition, 1);\n\n    document.addEventListener('scroll', checkScrollPosition);\n\n    delegate(document, 'click', '[data-toggle-mobile-menu]', () => {\n        const megaMenuActive = document.querySelector('.mega-menu--mobile-menu-active');\n        const viewport = new Viewport(Soho.breakpoints);\n\n        if (viewport.matches('nav-v3')) {\n            if (megaMenuActive) {\n                activateFirstNavButton();\n                updateNavButtonWidths();\n                trackActivate();\n            } else {\n                deactivateNavigationGroupList();\n                resetNavButtonWidths();\n            }\n        }\n\n        deactivateSearch();\n    });\n\n    delegate(document, 'click', loginRedirectSelector, (e) => {\n        const link = e.target.closest(loginRedirectSelector);\n        const isAccountEntry = /\\/account\\/(?:login|register)\\/?$/.test(window.location.pathname);\n        const currentUrl = `${window.location.pathname}${window.location.search}`;\n\n        link.href = isAccountEntry\n            ? '/account/login'\n            : `/account/login?redirect=${encodeURIComponent(currentUrl)}`;\n    });\n\n    delegate(document, 'click', '.navigation__group-header', (e) => {\n        const viewport = new Viewport(Soho.breakpoints);\n\n        if (viewport.matches('nav-v3')) {\n            toggleNavigationGroupList(e);\n        } else {\n            activateNavigationGroupList(e);\n        }\n    });\n\n    delegate(document, 'click', '[data-toggle-submenu], .navigation__group-header', (e) => {\n        getScrollableElements().forEach((element) => {\n            element.scrollTo(0, 0);\n        });\n    });\n\n    const observer = new MutationObserver(mutationList => {\n        for (const mutation of mutationList) {\n            if (mutation.target.classList.contains('navigation__section')) {\n                manageViewport(mutation.target.classList.contains('navigation__section--active'));\n            }\n        }\n    });\n\n    observer.observe(document.querySelector('.navigation'), { subtree: true, attributes: true, attributeFilter: ['class'] });\n\n    connectQuickBasketCount();\n}\n\nif (document.readyState === 'loading') {\n    document.addEventListener('DOMContentLoaded', () => {\n        observe();\n    });\n} else {\n    observe();\n}\n"],"mappings":"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"}