import{Component}from"@theme/component";import{morph}from"@theme/morph";import{DialogComponent,DialogCloseEvent}from"@theme/dialog";import{mediaQueryLarge,isMobileBreakpoint,getIOSVersion}from"@theme/utilities";import{StandardEvents}from"@shopify/events";const MAX_CACHE_SIZE=20;let productFormScriptsPromise=null;function ensureProductFormScripts(){if(window.Theme?.template?.name!=="product")return productFormScriptsPromise||(productFormScriptsPromise=Promise.all([import("@theme/product-form"),import("@theme/variant-picker")]),productFormScriptsPromise)}class LRUCache{#cache=new Map;#maxSize;constructor(maxSize=MAX_CACHE_SIZE){this.#maxSize=maxSize}get(key){if(!this.#cache.has(key))return;const value=this.#cache.get(key);return this.#cache.delete(key),this.#cache.set(key,value),value}set(key,value){if(this.#cache.has(key))this.#cache.delete(key);else if(this.#cache.size>=this.#maxSize){const oldestKey=this.#cache.keys().next().value;oldestKey&&this.#cache.delete(oldestKey)}this.#cache.set(key,value)}has(key){return this.#cache.has(key)}clear(){this.#cache.clear()}}export class QuickAddComponent extends Component{#cartUpdateAbortController=new AbortController;#abortController=null;#cache=new LRUCache(MAX_CACHE_SIZE);#pendingPages=new Map;#cacheGeneration=0;get productPageUrl(){const productCard=this.closest("product-card");return productCard?productCard.productPageUrl:this.closest("product-hotspot-component")?.getHotspotProductLink()?.href||""}#getSelectedVariantId(){return this.closest("product-card")?.getSelectedVariantId()??null}connectedCallback(){super.connectedCallback(),mediaQueryLarge.addEventListener("change",this.#closeQuickAddModal),document.addEventListener(StandardEvents.cartLinesUpdate,this.#handleCartUpdate,{signal:this.#cartUpdateAbortController.signal}),document.addEventListener(StandardEvents.productSelect,this.#handleProductSelectUpdate)}disconnectedCallback(){super.disconnectedCallback(),mediaQueryLarge.removeEventListener("change",this.#closeQuickAddModal),this.#abortController?.abort(),this.#cartUpdateAbortController.abort(),document.removeEventListener(StandardEvents.productSelect,this.#handleProductSelectUpdate)}#handleProductSelectUpdate=event=>{if(!(event.target instanceof HTMLElement)||event.target.closest("product-card")!==this.closest("product-card")||this.dataset.usesSellingPlans==="true"||this.dataset.rendersBothButtons!=="true")return;let quickAddButton=this.dataset.productOptionsCount==="1"?"add":"choose";quickAddButton==="add"&&this.#isSelectedVariantUnavailable()&&(quickAddButton="choose"),this.setAttribute("data-quick-add-button",quickAddButton)};#isSelectedVariantUnavailable(){return this.closest("product-card")?.variantPicker?.selectedOption?.dataset.optionAvailable==="false"}#handleCartUpdate=()=>{this.#cache.clear(),this.#cacheGeneration++,this.#pendingPages.clear()};handleClick=async event=>{event.preventDefault(),window.Theme?.template?.name!=="product"&&await ensureProductFormScripts();const currentUrl=this.productPageUrl;if(!currentUrl)return;if(this.dataset.usesSellingPlans==="true"){window.location.href=currentUrl;return}const productHtml=await this.fetchProductPage(currentUrl);!productHtml||currentUrl!==this.productPageUrl||(await this.updateQuickAddModal(productHtml),this.#openQuickAddModal())};#resetScroll(){const dialogComponent=document.getElementById("quick-add-dialog");if(!(dialogComponent instanceof QuickAddDialog))return;const productDetails=dialogComponent.querySelector(".product-details"),productMedia=dialogComponent.querySelector(".product-information__media");productDetails?.scrollTo({top:0,behavior:"instant"}),productMedia?.scrollTo({top:0,behavior:"instant"})}#stayVisibleUntilDialogCloses(dialogComponent){this.toggleAttribute("stay-visible",!0),dialogComponent.addEventListener(DialogCloseEvent.eventName,()=>this.toggleAttribute("stay-visible",!1),{once:!0})}#openQuickAddModal=()=>{const dialogComponent=document.getElementById("quick-add-dialog");if(!(dialogComponent instanceof QuickAddDialog))return;this.#stayVisibleUntilDialogCloses(dialogComponent),dialogComponent.showDialog();const dialog=dialogComponent.refs?.dialog;dialog&&dialog.addEventListener("animationstart",this.#resetScroll.bind(this),{once:!0})};#closeQuickAddModal=()=>{const dialogComponent=document.getElementById("quick-add-dialog");dialogComponent instanceof QuickAddDialog&&dialogComponent.closeDialog()};fetchProductPage(productPageUrl){if(!productPageUrl)return Promise.resolve(null);let key;try{key=new URL(productPageUrl,window.location.href).toString()}catch{return Promise.resolve(null)}const cached=this.#cache.get(key);if(cached)return Promise.resolve(cached);if(this.#pendingPages.has(key))return this.#pendingPages.get(key);const generation=this.#cacheGeneration,request=this.fetchQuickAddSection(key).then(html=>generation!==this.#cacheGeneration?null:(html&&this.#cache.set(key,html),html)).catch(()=>null).finally(()=>{this.#pendingPages.get(key)===request&&this.#pendingPages.delete(key)});return this.#pendingPages.set(key,request),request}async fetchQuickAddSection(productPageUrl){if(!productPageUrl)return null;const url=new URL(productPageUrl);url.searchParams.set("section_id","gco-quick-add-content"),this.#abortController?.abort();const controller=new AbortController;this.#abortController=controller;try{const response=await fetch(url.toString(),{signal:controller.signal});if(!response.ok)throw new Error(`Failed to fetch quick add section: HTTP error ${response.status}`);return await response.text()}catch(error){if(error.name==="AbortError")return null;throw error}finally{this.#abortController===controller&&(this.#abortController=null)}}async updateQuickAddModal(html){const modalContent=document.getElementById("quick-add-modal-content");!html||!modalContent||(modalContent.closest?.("quick-add-dialog")?.cancelColorRequest(),morph(modalContent,html),modalContent.closest?.("quick-add-dialog")?.refreshColors(),requestAnimationFrame(()=>{modalContent.querySelectorAll("carousel-component").forEach(el=>{typeof el.reinit=="function"&&el.reinit()})}),this.#syncVariantSelection(modalContent))}#syncVariantSelection(modalContent){const selectedVariantId=this.#getSelectedVariantId();if(!selectedVariantId)return;const modalInputs=modalContent.querySelectorAll('input[type="radio"][data-variant-id]');for(const input of modalInputs)if(input instanceof HTMLInputElement&&input.dataset.variantId===selectedVariantId&&!input.checked){input.checked=!0,input.dispatchEvent(new Event("change",{bubbles:!0}));break}}}customElements.get("quick-add-component")||customElements.define("quick-add-component",QuickAddComponent);class QuickAddDialog extends DialogComponent{#abortController=new AbortController;#colorRequest=null;#colorButtons=[];refreshColors=()=>{this.querySelectorAll(".quick-add-content .color-siblings").forEach(container=>{container.dataset.mode="quick-add",window.ColorSiblings?.hydrate(container)})};cancelColorRequest(){this.#colorRequest?.abort(),this.#colorRequest=null,this.#colorButtons.forEach(([button,disabled])=>{button.isConnected&&(button.disabled=disabled)}),this.#colorButtons=[],this.querySelector("#quick-add-modal-content")?.removeAttribute("aria-busy")}guardColorSubmit=event=>{this.#colorRequest&&(event.preventDefault(),event.stopImmediatePropagation())};handleColorClick=async event=>{if(event.button>0||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)return;const swatch=event.target.closest?.(".color-siblings__swatch[data-handle]"),container=swatch?.closest('.color-siblings[data-mode="quick-add"]');if(!container||container.dataset.mode!=="quick-add"||!this.contains(container))return;const url=new URL(swatch.href,window.location.origin);if(url.origin!==window.location.origin||(event.preventDefault(),swatch.getAttribute("aria-current")==="true"))return;const content=this.querySelector("#quick-add-modal-content");if(!content)return;this.cancelColorRequest();const controller=new AbortController;this.#colorRequest=controller;const originalHandle=container.dataset.currentHandle,targetHandle=swatch.dataset.handle;this.#colorButtons=Array.from(this.querySelectorAll('button[name="add"]'),button=>[button,button.disabled]),this.#colorButtons.forEach(([button])=>{button.disabled=!0}),content.setAttribute("aria-busy","true");let errorMessage=content.querySelector("[data-color-error-message]");errorMessage&&(errorMessage.textContent="");const timeout=setTimeout(()=>controller.abort(),1e4);try{url.searchParams.set("section_id","gco-quick-add-content");const response=await fetch(url.toString(),{signal:controller.signal});if(!response.ok)throw new Error("Color section unavailable");const html=await response.text();if(this.#colorRequest!==controller||!container.isConnected||container.dataset.currentHandle!==originalHandle||!this.refs.dialog?.open)return;if(new DOMParser().parseFromString(html,"text/html").querySelector(".color-siblings[data-current-handle]")?.dataset.currentHandle!==targetHandle)throw new Error("Color section product mismatch");this.#colorButtons.forEach(([button,disabled])=>{button.disabled=disabled}),this.#colorButtons=[],morph(content,html),this.refreshColors(),requestAnimationFrame(()=>{content.querySelectorAll("carousel-component").forEach(el=>el.reinit?.())})}catch{if(this.#colorRequest!==controller||!content.isConnected)return;errorMessage||(errorMessage=document.createElement("p"),errorMessage.setAttribute("data-color-error-message",""),errorMessage.setAttribute("role","alert"),content.appendChild(errorMessage)),errorMessage.textContent=this.dataset.colorError}finally{clearTimeout(timeout),this.#colorRequest===controller&&this.cancelColorRequest()}};#touchStartX=0;#touchStartY=0;#lastTouchY=0;#lastTouchTime=0;#velocity=0;#isDragging=!1;#dragConfirmed=!1;static SWIPE_THRESHOLD=100;static VELOCITY_THRESHOLD=.6;connectedCallback(){super.connectedCallback();const{signal}=this.#abortController;this.addEventListener(StandardEvents.cartLinesUpdate,this.handleCartUpdate,{signal}),this.addEventListener(StandardEvents.productSelect,this.#handleProductSelect,{signal}),this.addEventListener(DialogCloseEvent.eventName,this.#handleDialogClose,{signal}),this.addEventListener("click",this.handleColorClick,{signal}),this.addEventListener("submit",this.guardColorSubmit,{capture:!0,signal}),document.addEventListener("gco:color-siblings-ready",this.refreshColors,{signal}),this.#initDragHandle()}disconnectedCallback(){super.disconnectedCallback(),this.#abortController.abort(),this.cancelColorRequest()}#initDragHandle(){const dialog=this.refs.dialog,handle=this.refs.dragHandle;if(!dialog||!handle)return;const{signal}=this.#abortController;handle.addEventListener("click",()=>this.closeDialog(),{signal}),dialog.addEventListener("touchstart",this.#onTouchStart,{passive:!0,signal}),dialog.addEventListener("touchmove",this.#onTouchMove,{passive:!1,signal}),dialog.addEventListener("touchend",this.#onTouchEnd,{passive:!0,signal})}#onTouchStart=e=>{if(!isMobileBreakpoint())return;const touch=e.touches[0];touch&&(this.#touchStartX=touch.clientX,this.#touchStartY=touch.clientY,this.#lastTouchY=touch.clientY,this.#lastTouchTime=Date.now(),this.#isDragging=!0,this.#dragConfirmed=!1,this.#velocity=0)};#onTouchMove=e=>{if(!this.#isDragging||!isMobileBreakpoint())return;const touch=e.touches[0];if(!touch)return;const deltaY=touch.clientY-this.#touchStartY,deltaX=touch.clientX-this.#touchStartX,currentTime=Date.now(),timeDelta=currentTime-this.#lastTouchTime;timeDelta>0&&(this.#velocity=(touch.clientY-this.#lastTouchY)/timeDelta),this.#lastTouchY=touch.clientY,this.#lastTouchTime=currentTime;const dialog=this.refs.dialog;if(dialog instanceof HTMLElement){if(!this.#dragConfirmed){if(Math.abs(deltaX)>Math.abs(deltaY)){this.#isDragging=!1;return}if(dialog.scrollTop>5)return;if(deltaY>5)this.#dragConfirmed=!0,dialog.style.transition="none",dialog.style.animation="none";else return}if(this.#dragConfirmed){e.preventDefault();const moveY=Math.max(0,deltaY);dialog.style.transform=`translateY(${moveY}px)`;const opacity=Math.max(0,1-moveY/(window.innerHeight*.5));dialog.style.setProperty("--backdrop-opacity-multiplier",opacity.toString())}}};#onTouchEnd=e=>{if(!this.#isDragging||!this.#dragConfirmed){this.#isDragging=!1;return}this.#isDragging=!1;const dialog=this.refs.dialog;if(!(dialog instanceof HTMLElement))return;(e.changedTouches[0]?.clientY??0)-this.#touchStartY>QuickAddDialog.SWIPE_THRESHOLD||this.#velocity>QuickAddDialog.VELOCITY_THRESHOLD?this.#dismissFromDrag():(dialog.style.transition="transform 0.4s cubic-bezier(0.22, 1, 0.36, 1)",dialog.style.transform="",dialog.style.removeProperty("--backdrop-opacity-multiplier"))};async#dismissFromDrag(){const{dialog}=this.refs;dialog instanceof HTMLDialogElement&&(this.#isDragging=!1,this.#dragConfirmed=!1,dialog.style.removeProperty("--backdrop-opacity-multiplier"),await this.closeDialog(),dialog.style.transform="",dialog.style.transition="",dialog.style.animation="")}handleCartUpdate=event=>{event.promise?.then(({detail})=>{detail?.didError||this.closeDialog()}).catch(error=>{error?.name!=="AbortError"&&console.warn("[quick-add] Event promise rejected:",error)})};#handleProductSelect=event=>{event.promise?.then(({detail})=>{const html=detail?.html;if(!html)return;const galleryContainer=this.querySelector(".quick-add-content__media"),newGallerySource=html.querySelector(".quick-add-content__media");galleryContainer&&newGallerySource&&(morph(galleryContainer,newGallerySource),requestAnimationFrame(()=>{galleryContainer.querySelectorAll("carousel-component").forEach(el=>{typeof el.reinit=="function"&&el.reinit()})}));const productUrl=html.querySelector("variant-picker")?.dataset?.productUrl;if(!productUrl)return;const variantId=detail?.resource?.id,url=new URL(productUrl,window.location.origin);variantId&&url.searchParams.set("variant",variantId);const href=url.pathname+url.search,viewDetailsLink=this.querySelector(".quick-add-content__view-details"),productTitleLink=this.querySelector(".quick-add-content__title");viewDetailsLink&&(viewDetailsLink.href=href),productTitleLink&&(productTitleLink.href=href)}).catch(error=>{error?.name!=="AbortError"&&console.warn("[quick-add] Event promise rejected:",error)})};#handleDialogClose=()=>{this.cancelColorRequest();const iosVersion=getIOSVersion();!iosVersion||iosVersion.major>=17||iosVersion.major===16&&iosVersion.minor>=4||requestAnimationFrame(()=>{const grid=document.querySelector("#ResultsList [product-grid-view]");if(grid){const currentWidth=grid.getBoundingClientRect().width;grid.style.width=`${currentWidth-1}px`,requestAnimationFrame(()=>{grid.style.width=""})}})}}customElements.get("quick-add-dialog")||customElements.define("quick-add-dialog",QuickAddDialog); //# sourceMappingURL=/cdn/shop/t/35/assets/gco-quick-add.js.map?v=160503396939207541111793372366