1if (!customElements.get('quick-add-modal')) { 2 customElements.define( 3 'quick-add-modal', 4 class QuickAddModal extends ModalDialog { 5 constructor() { 6 super(); 7 this.modalContent = this.querySelector('[id^="QuickAddInfo-"]'); 8 9 this.addEventListener('product-info:loaded', ({ target }) => { 10 target.addPreProcessCallback(this.preprocessHTML.bind(this)); 11 }); 12 } 13 14 hide(preventFocus = false) { 15 const cartNotification = document.querySelector('cart-notification') || document.querySelector('cart-drawer'); 16 if (cartNotification) cartNotification.setActiveElement(this.openedBy); 17 this.modalContent.innerHTML = ''; 18 19 if (preventFocus) this.openedBy = null; 20 super.hide(); 21 } 22 23 show(opener) { 24 25 opener.setAttribute('aria-disabled', true); 26 opener.classList.add('loading'); 27 opener.querySelector('.loading__spinner').classList.remove('hidden'); 28 29 fetch(opener.getAttribute('data-product-url')) 30 .then((response) => response.text()) 31 .then((responseText) => { 32 const responseHTML = new DOMParser().parseFromString(responseText, 'text/html'); 33 const productElement = responseHTML.querySelector('product-info'); 34 35 this.preprocessHTML(productElement); 36 HTMLUpdateUtility.setInnerHTML(this.modalContent, productElement.outerHTML); 37 if (typeof fc_lazyBlurImages === 'function') { 38 fc_lazyBlurImages(); 39 } 40 if (window.Shopify && Shopify.PaymentButton) { 41 Shopify.PaymentButton.init(); 42 } 43 if (window.ProductModel) window.ProductModel.loadShopifyXR(); 44 45 super.show(opener); 46 }) 47 .finally(() => { 48 opener.removeAttribute('aria-disabled'); 49 opener.classList.remove('loading'); 50 opener.querySelector('.loading__spinner').classList.add('hidden'); 51 }); 52 } 53 54 preprocessHTML(productElement) { 55 productElement.classList.forEach((classApplied) => { 56 if (classApplied.startsWith('color-') || classApplied === 'gradient') 57 this.modalContent.classList.add(classApplied); 58 }); 59 this.preventDuplicatedIDs(productElement); 60 this.removeDOMElements(productElement); 61 this.removeGalleryListSemantic(productElement); 62 this.updateImageSizes(productElement); 63 this.preventVariantURLSwitching(productElement); 64 } 65 66 preventVariantURLSwitching(productElement) { 67 productElement.setAttribute('data-update-url', 'false'); 68 } 69 70 removeDOMElements(productElement) { 71 const pickupAvailability = productElement.querySelector('pickup-availability'); 72 if (pickupAvailability) pickupAvailability.remove(); 73 74 const productModal = productElement.querySelector('product-modal'); 75 if (productModal) productModal.remove(); 76 77 const modalDialog = productElement.querySelectorAll('modal-dialog'); 78 if (modalDialog) modalDialog.forEach((modal) => modal.remove()); 79 } 80 81 preventDuplicatedIDs(productElement) { 82 const sectionId = productElement.dataset.section; 83 84 const oldId = sectionId; 85 const newId = `quickadd-${sectionId}`; 86 productElement.innerHTML = productElement.innerHTML.replaceAll(oldId, newId); 87 Array.from(productElement.attributes).forEach((attribute) => { 88 if (attribute.value.includes(oldId)) { 89 productElement.setAttribute(attribute.name, attribute.value.replace(oldId, newId)); 90 } 91 }); 92 93 productElement.dataset.originalSection = sectionId; 94 } 95 96 removeGalleryListSemantic(productElement) { 97 const galleryList = productElement.querySelector('[id^="Slider-Gallery"]'); 98 if (!galleryList) return; 99 100 galleryList.setAttribute('role', 'presentation'); 101 galleryList.querySelectorAll('[id^="Slide-"]').forEach((li) => li.setAttribute('role', 'presentation')); 102 } 103 104 updateImageSizes(productElement) { 105 if (typeof fc_lazyBlurImages === 'function') { 106 fc_lazyBlurImages(); 107 } 108 const product = productElement.querySelector('.product'); 109 const desktopColumns = product?.classList.contains('product--columns'); 110 if (!desktopColumns) return; 111 112 const mediaImages = product.querySelectorAll('.product__media img'); 113 if (!mediaImages.length) return; 114 115 let mediaImageSizes = 116 '(min-width: 1000px) 715px, (min-width: 750px) calc((100vw - 11.5rem) / 2), calc(100vw - 4rem)'; 117 118 if (product.classList.contains('product--medium')) { 119 mediaImageSizes = mediaImageSizes.replace('715px', '605px'); 120 } else if (product.classList.contains('product--small')) { 121 mediaImageSizes = mediaImageSizes.replace('715px', '495px'); 122 } 123
124 mediaImages.forEach((img) => img.setAttribute('sizes', mediaImageSizes)); 125 } 126 } 127 ); 128}
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.