{"version":3,"file":"turbo_frame_navigation-Bg9MeJjc.js","names":[],"sources":["../../../app/frontend/entrypoints/turbo_frame_navigation.ts"],"sourcesContent":["// app/frontend/entrypoints/turbo_frame_navigation.ts\n\nconst SCROLLABLE_OVERFLOW = [\"auto\", \"scroll\", \"overlay\"];\n\nlet hashOnlyTransition = false;\n\nfunction pathAndSearch(url: string) {\n const { pathname, search } = new URL(url, window.location.href);\n return pathname + search;\n}\n\nexport function findScrollableAncestor(element: HTMLElement): HTMLElement | null {\n let current = element.parentElement;\n\n while (current) {\n const { overflow, overflowX, overflowY } = window.getComputedStyle(current);\n const isScrollable =\n SCROLLABLE_OVERFLOW.includes(overflow) ||\n SCROLLABLE_OVERFLOW.includes(overflowX) ||\n SCROLLABLE_OVERFLOW.includes(overflowY) ||\n current.classList.contains(\"overflow-auto\") ||\n current.classList.contains(\"overflow-scroll\");\n\n if (isScrollable) {\n return current;\n }\n\n current = current.parentElement;\n }\n\n return null;\n}\n\nfunction preserveScrollOnFrameRender(frame: HTMLElement) {\n if (frame.dataset.preserveScroll !== \"true\" || frame.hasAttribute(\"autoscroll\")) return;\n\n const scrollContainer = findScrollableAncestor(frame);\n\n if (scrollContainer) {\n const { scrollLeft, scrollTop } = scrollContainer;\n frame.addEventListener(\n \"turbo:frame-render\",\n () =>\n requestAnimationFrame(() => {\n scrollContainer.scrollLeft = scrollLeft;\n scrollContainer.scrollTop = scrollTop;\n }),\n { once: true }\n );\n return;\n }\n\n const savedX = window.scrollX;\n const savedY = window.scrollY;\n frame.addEventListener(\n \"turbo:frame-render\",\n () => requestAnimationFrame(() => window.scrollTo(savedX, savedY)),\n { once: true }\n );\n}\n\n// Preserve scroll only for frames that explicitly opt in.\ndocument.addEventListener(\"turbo:before-frame-render\", (event) => {\n const frame = event.target;\n if (!(frame instanceof HTMLElement)) return;\n\n preserveScrollOnFrameRender(frame);\n});\n\n// Handle Turbo frame loads to update the browser URL naturally\ndocument.addEventListener(\"turbo:frame-load\", (event) => {\n const frame = event.target;\n // Only care about our main-content frame\n if (frame instanceof HTMLElement && frame.id === \"main-content\") {\n const url = frame.getAttribute(\"src\");\n if (url && url !== window.location.pathname + window.location.search) {\n // Use pushState to create proper history entries for back/forward navigation\n window.history.pushState({ turbo: true }, \"\", url);\n }\n }\n});\n\nexport function onHashChange(event: HashChangeEvent) {\n hashOnlyTransition = pathAndSearch(event.oldURL) === pathAndSearch(event.newURL);\n}\n\nexport function handlePopState(hashOnly: boolean) {\n if (hashOnly) return;\n\n const frame = document.querySelector(\"turbo-frame#main-content\");\n if (frame) {\n const currentPath = window.location.pathname + window.location.search;\n const frameSrc = frame.getAttribute(\"src\");\n\n // Only update the frame if it doesn't match the current URL\n if (frameSrc !== currentPath) {\n frame.setAttribute(\"src\", currentPath);\n }\n } else {\n // If there's no Turbo frame on the current page (like inventory index with React component),\n // do a full page reload to properly load the page structure\n window.location.reload();\n }\n}\n\n// popstate fires before hashchange, so decide one task later\nexport function onPopState() {\n hashOnlyTransition = false;\n setTimeout(() => {\n const hashOnly = hashOnlyTransition;\n hashOnlyTransition = false;\n handlePopState(hashOnly);\n }, 0);\n}\n\nwindow.addEventListener(\"hashchange\", onHashChange);\nwindow.addEventListener(\"popstate\", onPopState);\n"],"mappings":"AAEA,IAAM,EAAsB,CAAC,OAAQ,SAAU,SAAS,EAEpD,EAAqB,GAEzB,SAAS,EAAc,EAAa,CAClC,GAAM,CAAE,WAAU,UAAW,IAAI,IAAI,EAAK,OAAO,SAAS,IAAI,EAC9D,OAAO,EAAW,CACpB,CAEA,SAAgB,EAAuB,EAA0C,CAC/E,IAAI,EAAU,EAAQ,cAEtB,KAAO,GAAS,CACd,GAAM,CAAE,WAAU,YAAW,aAAc,OAAO,iBAAiB,CAAO,EAQ1E,GANE,EAAoB,SAAS,CAAQ,GACrC,EAAoB,SAAS,CAAS,GACtC,EAAoB,SAAS,CAAS,GACtC,EAAQ,UAAU,SAAS,eAAe,GAC1C,EAAQ,UAAU,SAAS,iBAAiB,EAG5C,OAAO,EAGT,EAAU,EAAQ,aACpB,CAEA,OAAO,IACT,CAEA,SAAS,EAA4B,EAAoB,CACvD,GAAI,EAAM,QAAQ,iBAAmB,QAAU,EAAM,aAAa,YAAY,EAAG,OAEjF,IAAM,EAAkB,EAAuB,CAAK,EAEpD,GAAI,EAAiB,CACnB,GAAM,CAAE,aAAY,aAAc,EAClC,EAAM,iBACJ,yBAEE,0BAA4B,CAC1B,EAAgB,WAAa,EAC7B,EAAgB,UAAY,CAC9B,CAAC,EACH,CAAE,KAAM,EAAK,CACf,EACA,MACF,CAEA,IAAM,EAAS,OAAO,QAChB,EAAS,OAAO,QACtB,EAAM,iBACJ,yBACM,0BAA4B,OAAO,SAAS,EAAQ,CAAM,CAAC,EACjE,CAAE,KAAM,EAAK,CACf,CACF,CAGA,SAAS,iBAAiB,4BAA8B,GAAU,CAChE,IAAM,EAAQ,EAAM,OACd,aAAiB,aAEvB,EAA4B,CAAK,CACnC,CAAC,EAGD,SAAS,iBAAiB,mBAAqB,GAAU,CACvD,IAAM,EAAQ,EAAM,OAEpB,GAAI,aAAiB,aAAe,EAAM,KAAO,eAAgB,CAC/D,IAAM,EAAM,EAAM,aAAa,KAAK,EAChC,GAAO,IAAQ,OAAO,SAAS,SAAW,OAAO,SAAS,QAE5D,OAAO,QAAQ,UAAU,CAAE,MAAO,EAAK,EAAG,GAAI,CAAG,CAErD,CACF,CAAC,EAED,SAAgB,EAAa,EAAwB,CACnD,EAAqB,EAAc,EAAM,MAAM,IAAM,EAAc,EAAM,MAAM,CACjF,CAEA,SAAgB,EAAe,EAAmB,CAChD,GAAI,EAAU,OAEd,IAAM,EAAQ,SAAS,cAA2B,0BAA0B,EAC5E,GAAI,EAAO,CACT,IAAM,EAAc,OAAO,SAAS,SAAW,OAAO,SAAS,OAC9C,EAAM,aAAa,KAGhC,IAAa,GACf,EAAM,aAAa,MAAO,CAAW,CAEzC,MAGE,OAAO,SAAS,OAAO,CAE3B,CAGA,SAAgB,GAAa,CAC3B,EAAqB,GACrB,eAAiB,CACf,IAAM,EAAW,EACjB,EAAqB,GACrB,EAAe,CAAQ,CACzB,EAAG,CAAC,CACN,CAEA,OAAO,iBAAiB,aAAc,CAAY,EAClD,OAAO,iBAAiB,WAAY,CAAU"}