{"version":3,"file":"modal-manager-section-xxxxxxxxxxxxxxxxxxxx.min.js","mappings":"YAUA,IAAIA,EAAkC,KAqEtC,SAASC,EAAYC,GAInBA,EAAMC,gBACR,CAKA,SAASC,EAAcC,EAAkBC,GACvC,IAAKD,EACH,OAGF,MAAME,EAAUF,EAAQE,QAAQD,GAEhC,GAAIC,EACF,OAAOA,EAGT,MAAMC,EAAOH,EAAQI,cAGrB,MAMO,SANUD,EACRJ,EAAcI,EAAKE,KAAMJ,QADlC,CAGF,CA6BA,SAASK,EAAcT,GACrB,GAAIA,aAAiBU,eACA,WAAfV,EAAMW,KACR,OAIJ,MAAMC,EAAc,IAAIC,YAAY,iBAAkB,CACpDC,YAAY,EACZC,OAAQ,CACNZ,QAASL,KAGbkB,cAAcJ,EAChB,CAeAK,iBAAiB,uBAvHjB,SAA8BjB,GAC5B,MAAMkB,EAAQlB,EAAMe,OAAOZ,QAC3BL,EAAcoB,EACd,MAAMC,EAAejB,EAAcgB,EAAO,oBAE1CE,SAASC,KAAKJ,iBAAiB,YAAalB,GAiE9C,WACE,MAAMuB,EAASF,SAASG,eAAe,gBAGvCD,EAAOE,oBAAoB,QAASf,GACpCW,SAASI,oBAAoB,QAASf,GAEtCa,EAAOL,iBAAiB,QAASR,GACjCW,SAASH,iBAAiB,QAASR,GAEnC,MAAMgB,EAAiBC,OAAOC,WAAaP,SAASQ,gBAAgBC,YAChEC,OAAOC,UAAUN,IACnBL,SAASQ,gBAAgBI,MAAMC,YAAY,oBAAqBR,EAAiB,MAGnFL,SAASQ,gBAAgBM,UAAUC,IAAI,gBAEvCb,EAAOY,UAAUC,IAAI,SACvB,CAjFEC,GAGA,MAAMC,EAAWjB,SAASkB,iBAA8B,oBACxD,IAAK,MAAMC,KAAWF,EAChBE,IAAYpB,GAAiBoB,EAAQL,UAAUM,SAAS,uBAC1DD,EAAQE,aAAa,QAAS,GAGpC,GAwGAxB,iBAAiB,wBAlGjB,SAA+ByB,GAC7B,MAAML,EAAWjB,SAASkB,iBAAiB,oBAC3C,IAAK,MAAMC,KAAWF,EACpBE,EAAQI,gBAAgB,SAG1BvB,SAASC,KAAKG,oBAAoB,YAAazB,GAiFjD,WACE,MAAMuB,EAASF,SAASG,eAAe,gBACvCD,EAAOE,oBAAoB,QAASf,GACpCW,SAASI,oBAAoB,QAASf,GAEtCW,SAASQ,gBAAgBM,UAAUU,OAAO,gBAE1CtB,EAAOY,UAAUU,OAAO,SAC1B,CAvFEC,GACA/C,EAAc,IAChB","sources":["webpack://lange/./scripts/sections/modal-manager/index.ts"],"sourcesContent":["/**\n * Modal Manager library. Copied from Lange with small adjustments.\n *\n * TODO refactor all modals to use this library.\n */\n\n/**\n * The currently active modal dialog element or null if no modal dialog is active.\n * Used to ignore close requests for non-active modals.\n */\nlet activeModal: HTMLElement | null = null;\n\ntype ModalCloseRequestedEvent = CustomEvent<{\n  element: HTMLElement;\n}>;\n\ntype ModalShowRequestedEvent = CustomEvent<{\n  element: HTMLElement;\n}>;\n\ntype ShroudClickedEvent = CustomEvent<{\n  element: HTMLElement;\n}>;\n\ndeclare global {\n  interface WindowEventMap {\n    'modal-close-requested': ModalCloseRequestedEvent;\n    'modal-show-requested': ModalShowRequestedEvent;\n\n    /**\n     * Fired when a user clicks on the shroud.\n     */\n    'shroud-clicked': ShroudClickedEvent;\n  }\n}\n\n/**\n * Make all the Shopify sections (including the header and the footer, but excluding a section\n * containing a modal dialog) inert. Disable background scrolling and hide the Attentive modal\n * window if any is active.\n *\n * This is a relatively safe and widely supported method of disabling the active background elements\n * when displaying modal windows. The active elements have to be disabled to avoid a11y problems\n * with keyboard browsing.\n */\nfunction onModalShowRequested(event: ModalShowRequestedEvent) {\n  const modal = event.detail.element;\n  activeModal = modal;\n  const modalSection = globalClosest(modal, '.shopify-section');\n\n  document.body.addEventListener('touchmove', onTouchMove);\n\n  showShroud();\n\n  // Make other sections inert unless the sections are flagged as always active.\n  const sections = document.querySelectorAll<HTMLElement>('.shopify-section');\n  for (const section of sections) {\n    if (section !== modalSection && !section.classList.contains('a11y-always-active')) {\n      section.setAttribute('inert', '');\n    }\n  }\n}\n\n/**\n * Clear the inert attribute for all Shopify sections, enable the background scrolling and show the\n * Attentive dialog if it was active before.\n */\nfunction onModalCloseRequested(_event: ModalCloseRequestedEvent) {\n  const sections = document.querySelectorAll('.shopify-section');\n  for (const section of sections) {\n    section.removeAttribute('inert');\n  }\n\n  document.body.removeEventListener('touchmove', onTouchMove);\n\n  hideShroud();\n  activeModal = null;\n}\n\nfunction onTouchMove(event: TouchEvent) {\n  // TODO: this method doesn't work as the handler is not installed with { passive: false }\n  // Currently it just generates browser warnings. Setting the passive option breaks mobile scroll.\n  // Check if this is needed at all and fix or remove it.\n  event.preventDefault();\n}\n\n/**\n * Works like `Element.closest()` method but crosses the ShadowRoot boundaries\n */\nfunction globalClosest(element: Element, selector: string) {\n  if (!element) {\n    return;\n  }\n\n  const closest = element.closest(selector);\n\n  if (closest) {\n    return closest;\n  }\n\n  const root = element.getRootNode();\n  // under some circumstances `getRootNode()` may return the document, the element itself etc\n  // we are only interested in cases where the root is a custom element's ShadowRoot\n  if (isShadowRoot(root)) {\n    return globalClosest(root.host, selector);\n  }\n}\n\nfunction isShadowRoot(node: Node): node is ShadowRoot {\n  return 'host' in node;\n}\n\n/**\n * This function supports calls to show the shroud even if it is already shown.\n */\nfunction showShroud() {\n  const shroud = document.getElementById('modal-shroud');\n\n  // just in case of a bug/inconsistency in calling this function we clean up any previous listeners\n  shroud.removeEventListener('click', onShroudClick);\n  document.removeEventListener('keyup', onShroudClick);\n\n  shroud.addEventListener('click', onShroudClick);\n  document.addEventListener('keyup', onShroudClick);\n\n  const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;\n  if (Number.isInteger(scrollbarWidth)) {\n    document.documentElement.style.setProperty('--scrollbar-width', scrollbarWidth + 'px');\n  }\n\n  document.documentElement.classList.add('js-no-scroll');\n\n  shroud.classList.add('active');\n}\n\nfunction onShroudClick(event: KeyboardEvent | MouseEvent) {\n  if (event instanceof KeyboardEvent) {\n    if (event.code !== 'Escape') {\n      return;\n    }\n  }\n\n  const shroudEvent = new CustomEvent('shroud-clicked', {\n    cancelable: false,\n    detail: {\n      element: activeModal\n    }\n  });\n  dispatchEvent(shroudEvent);\n}\n\n/**\n * This function supports calls to hide the shroud even if it is already hidden.\n */\nfunction hideShroud() {\n  const shroud = document.getElementById('modal-shroud');\n  shroud.removeEventListener('click', onShroudClick);\n  document.removeEventListener('keyup', onShroudClick);\n\n  document.documentElement.classList.remove('js-no-scroll');\n\n  shroud.classList.remove('active');\n}\n\naddEventListener('modal-show-requested', onModalShowRequested);\naddEventListener('modal-close-requested', onModalCloseRequested);\n"],"names":["activeModal","onTouchMove","event","preventDefault","globalClosest","element","selector","closest","root","getRootNode","host","onShroudClick","KeyboardEvent","code","shroudEvent","CustomEvent","cancelable","detail","dispatchEvent","addEventListener","modal","modalSection","document","body","shroud","getElementById","removeEventListener","scrollbarWidth","window","innerWidth","documentElement","clientWidth","Number","isInteger","style","setProperty","classList","add","showShroud","sections","querySelectorAll","section","contains","setAttribute","_event","removeAttribute","remove","hideShroud"],"sourceRoot":""}