1if (!customElements.get('quick-add-modal')) { 2 customElements.define('quick-add-modal', class QuickAddModal extends ModalDialog { 3 constructor() { 4 super(); 5 this.modalContent = this.querySelector('[id^="QuickAddInfo-"]'); 6 } 7 8 hide(preventFocus = false) { 9 document.body.addEventListener('modalClosed', () => { 10 setTimeout(() => { this.modalContent.innerHTML = ''; }); 11 }, { once: true }); 12 if (preventFocus) this.openedBy = null; 13 super.hide(); 14 } 15 16 show(opener) { 17 opener.setAttribute('aria-disabled', true); 18 opener.classList.add('loading'); 19 opener.querySelector('.loading-overlay__spinner').classList.remove('hidden'); 20 21 fetch(opener.getAttribute('data-product-url')) 22 .then((response) => response.text()) 23 .then((responseText) => { 24 const responseHTML = new DOMParser().parseFromString(responseText, 'text/html'); 25 this.productElement = responseHTML.querySelector('section[id^="MainProduct-"]'); 26 this.preventDuplicatedIDs(); 27 this.removeDOMElements(); 28 this.setInnerHTML(this.modalContent, this.productElement.innerHTML); 29 30 if (window.Shopify && Shopify.PaymentButton) { 31 Shopify.PaymentButton.init(); 32 } 33 34 if (window.ProductModel) window.ProductModel.loadShopifyXR(); 35 36 this.preventVariantURLSwitching(); 37 super.show(opener); 38 }) 39 .finally(() => { 40 opener.removeAttribute('aria-disabled'); 41 opener.classList.remove('loading'); 42 opener.querySelector('.loading-overlay__spinner').classList.add('hidden'); 43 }); 44 } 45 46 setInnerHTML(element, html) { 47 element.innerHTML = html; 48 49 // Reinjects the script tags to allow execution. By default, scripts are disabled when using element.innerHTML. 50 element.querySelectorAll('script').forEach(oldScriptTag => { 51 const newScriptTag = document.createElement('script'); 52 Array.from(oldScriptTag.attributes).forEach(attribute => { 53 newScriptTag.setAttribute(attribute.name, attribute.value) 54 }); 55 newScriptTag.appendChild(document.createTextNode(oldScriptTag.innerHTML)); 56 oldScriptTag.parentNode.replaceChild(newScriptTag, oldScriptTag); 57 }); 58 } 59 60 preventVariantURLSwitching() { 61 this.modalContent.querySelector('variant-radios,variant-selects') && this.modalContent.querySelector('variant-radios,variant-selects').setAttribute('data-update-url', 'false'); 62 } 63 64 removeDOMElements() { 65 const pickupAvailability = this.productElement.querySelector('pickup-availability'); 66 if (pickupAvailability) pickupAvailability.remove(); 67 68 this.removeElements('.popup-modal__opener'); 69 this.removeElements('product-modal'); 70 this.removeElements('modal-dialog'); 71 this.removeElements('toggle-component'); 72 this.removeElements('share-button'); 73 this.removeElements('sticky-cart-modal'); 74 this.removeElements('.variants-modal__button'); 75 this.removeElements('.line-after-tabs'); 76 this.removeElements('product-recommendations'); 77 this.removeElements('.product__media-icon'); 78 this.removeElements('.product__media-toggle'); 79 80 var element = false; 81 82 element = this.productElement.querySelector('.product__media-sticky'); 83 element && element.classList.remove('product__media-sticky'); 84 85 element = this.productElement.querySelector('.product--thumbnail_slider'); 86 element && element.classList.add('quick-add-modal'); 87 } 88 89 removeElements(value){ 90 var elements = this.productElement.querySelectorAll(value); 91 elements.forEach((element) => { 92 element.remove(); 93 }); 94 } 95 96 preventDuplicatedIDs() { 97 const sectionId = this.productElement.dataset.section; 98 this.productElement.innerHTML = this.productElement.innerHTML.replaceAll(sectionId, `quickadd-${ sectionId }`); 99 this.productElement.querySelectorAll('variant-selects, variant-radios').forEach((variantSelect) => { 100 variantSelect.dataset.originalSection = sectionId; 101 }); 102 } 103 }); 104}
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.