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