1import{EVENTS}from"util.events";class BlockVariantPicker extends HTMLElement{connectedCallback(){this.productInfo=new Map,this.addEventListener("change",this.handleVariantChange.bind(this)),this.addEventListener("touchstart",this.handleElementEvent.bind(this)),this.addEventListener("mousedown",this.handleElementEvent.bind(this))}handleElementEvent(event){let target=event.target;target?.tagName!=="INPUT"&&(target=event.target.closest("label")?.querySelector('input[type="radio"]'),!target?.checked&&target?.click()),target&&(this.updateOptions(target),this.updateMasterId(),this.currentVariant&&this.getProductInfo())}async handleVariantChange(event){if(this.updateOptions(),this.updateMasterId(event.target),"dynamicVariantsEnabled"in this.dataset&&this.updateVariantStatuses(event.target),this.updateColorNames(),this.dispatchEvent(new CustomEvent(`${EVENTS.variantChange}:${this.dataset.sectionId}:${this.dataset.productId}`,{bubbles:!0,detail:{sectionId:this.dataset.sectionId,html:null,variant:this.currentVariant,loading:!0}})),this.currentVariant){this.updateURL();let html=null;try{html=await this.getProductInfo()}catch(error){console.error("Failed to fetch product info:",error)}this.dispatchEvent(new CustomEvent(`${EVENTS.variantChange}:${this.dataset.sectionId}:${this.dataset.productId}`,{bubbles:!0,detail:{sectionId:this.dataset.sectionId,html,variant:this.currentVariant,loading:!1}}))}else this.dispatchEvent(new CustomEvent(`${EVENTS.variantChange}:${this.dataset.sectionId}:${this.dataset.productId}`,{bubbles:!0,detail:{sectionId:this.dataset.sectionId,html:null,variant:null,loading:!1}}))}updateOptions(target){this.options=Array.from(this.querySelectorAll("select, fieldset"),element=>{if(element.tagName==="SELECT")return element.value;if(element.tagName==="FIELDSET"){const targetInFieldset=target&&element.contains(target)?target:null;return Array.from(element.querySelectorAll("input")).find(radio=>targetInFieldset?radio===targetInFieldset:radio.checked)?.value}})}updateMasterId(target){const availableFullMatch=this.getFullMatch(!0),closestAvailableMatch=this.getClosestAvailableMatch(target),fullMatch=this.getFullMatch(!1);this.currentVariant="dynamicVariantsEnabled"in this.dataset?availableFullMatch||closestAvailableMatch||fullMatch||null:fullMatch||null}getFullMatch(needsToBeAvailable){return this.getVariantData().find(variant=>{const isMatch=this.options.every((value,index)=>variant[this.getOptionName(index)]===value);return needsToBeAvailable?isMatch&&variant.available:isMatch})}getClosestAvailableMatch(lastSelectedOption){return lastSelectedOption?(lastSelectedOption&&this.getVariantData().filter(variant=>this.options.filter((_,index)=>index+1<=this.numberFromOptionKey(lastSelectedOption.dataset.index)).every((value,index)=>variant[this.getOptionName(index)]===value)&&variant.available)).reduce((bestMatch,variant)=>{if(bestMatch===null)return variant;const bestMatchCount=this.getWeightedOptionMatchCount(bestMatch,lastSelectedOption);return this.getWeightedOptionMatchCount(variant,lastSelectedOption)>bestMatchCount?variant:bestMatch},null):null}getWeightedOptionMatchCount(variant){return this.options.reduce((count,value,index)=>{const weightedCount=3-index;return variant[this.getOptionName(index)]===value?count+weightedCount:count},0)}numberFromOptionKey(key){return parseInt(key.substr(-1))}getOptionName(index){return`option${index+1}`}getVariantData(){return this.variantData=this.variantData||JSON.parse(this.querySelector('[type="application/json"]').textContent),this.variantData}updateVariantStatuses(lastSelectedOption){const selectedOptionOneVariants=this.variantData.filter(variant=>this.querySelector(":checked").value===variant.option1),inputWrappers=[...this.querySelectorAll("fieldset, .variant-wrapper")];inputWrappers.forEach((option,index)=>{if(index===0||lastSelectedOption.parentElement===option)return;const optionInputs=[...option.querySelectorAll('input[type="radio"], option')],previousOptionSelected=inputWrappers[index-1].querySelector(":checked").value,availableOptionInputsValue=selectedOptionOneVariants.filter(variant=>variant.available&&variant[`option${index}`]===previousOptionSelected).map(variantOption=>variantOption[this.getOptionName(index)]);this.setInputAvailability(optionInputs,availableOptionInputsValue)})}updateColorNames(){this.querySelectorAll("fieldset").forEach(fieldset=>{const input=fieldset.querySelector("input:checked");if(!input)return;const colorLabel=fieldset.querySelector("[data-variant-color-label]");colorLabel&&(colorLabel.textContent=input.value)})}setInputAvailability(elementList,availableValuesList){elementList.forEach(element=>{const value=element.getAttribute("value"),availableElement=availableValuesList.includes(value);element.tagName==="INPUT"?(element.parentElement.classList.toggle("disabled",!availableElement),this.currentVariant?.[element.dataset.index]===value&&(element.checked=!0)):(element.toggleAttribute("disabled",!availableElement),this.currentVariant?.[element.dataset.index]===value&&(element.selected=!0))})}updateURL(){!this.currentVariant||!("updateUrl"in this.dataset)||window.history.replaceState({},"",`${this.dataset.url}?variant=${this.currentVariant.id}`)}getProductInfo(){const requestedVariantId=this.currentVariant.id;return this.productInfo.has(requestedVariantId)?this.productInfo.get(requestedVariantId):(this.productInfo.set(requestedVariantId,fetch(`${this.dataset.url}?variant=${requestedVariantId}§ion_id=${this.dataset.sectionId}`).then(response=>response.text()).then(responseText=>new DOMParser().parseFromString(responseText,"text/html"))),this.productInfo.get(requestedVariantId))}}customElements.define("block-variant-picker",BlockVariantPicker); 2//# sourceMappingURL=/cdn/shop/t/40/assets/block.product-variant-picker.js.map?v=114817416060497964331776998780
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.