Skip to content

Commit

Permalink
v15 fixes (Shopify#3547)
Browse files Browse the repository at this point in the history
* [Product] Zoom on hover fix on variant change (Shopify#3511)

* Zoom on hover fix on variant change

* add conditional

* Add early return in updateQuantityRules function if no quantity selector is present (Shopify#3515)

* Fix bug where request url contains duplicated params when switching before the prior response is returned (Shopify#3521)

* Fixes bug where image flashes when switching to variant with the same featured image; fixes bug where variant without featured image would fallback to the product image (Shopify#3516)

Fix issue with thumbnail not updating

* Fixed bug when reading selected option values. Removed unused script tag containing variant json. (Shopify#3520)

* escape titles that weren't (Shopify#3514)

* Support multiple product templates for the same combined listing (Shopify#3526)

* Updated quick order list to rely on the variant title field (Shopify#3528)

* Release15fix (Shopify#3531)

* Revert "Update from Shopify for theme dawn/release/15.0.0"

This reverts commit 5b20d89.

* Revert "Update from Shopify for theme dawn/release/15.0.0"

This reverts commit f0b822d.

* Revert "Update from Shopify for theme dawn/release/15.0.0"

This reverts commit 64e1d8e.

* Revert "Update from Shopify for theme dawn/release/15.0.0"

This reverts commit a8a7529.

---------

Co-authored-by: Ludo <ludo.segura@shopify.com>
Co-authored-by: Arthur <48017311+Roi-Arthur@users.noreply.github.com>
Co-authored-by: Lars Hoffbeck <lars.hoffbeck@shopify.com>
Co-authored-by: shopify[bot] <79544226+shopify[bot]@users.noreply.github.com>
  • Loading branch information
5 people authored and NikoBerger committed Jul 12, 2024
1 parent c479165 commit 0a4e016
Show file tree
Hide file tree
Showing 14 changed files with 549 additions and 544 deletions.
5 changes: 0 additions & 5 deletions assets/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,4 @@ const PUB_SUB_EVENTS = {
optionValueSelectionChange: 'option-value-selection-change',
variantChange: 'variant-change',
cartError: 'cart-error',
sectionRefreshed: 'section-refreshed',
};

const SECTION_REFRESH_RESOURCE_TYPE = {
product: 'product',
};
20 changes: 8 additions & 12 deletions assets/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -1059,8 +1059,7 @@ class VariantSelects extends HTMLElement {
connectedCallback() {
this.addEventListener('change', (event) => {
const target = this.getInputForEventTarget(event.target);
this.currentVariant = this.getVariantData(target.id);
this.updateSelectedSwatchValue(event);
this.updateSelectionMetadata(event);

publish(PUB_SUB_EVENTS.optionValueSelectionChange, {
data: {
Expand All @@ -1072,10 +1071,15 @@ class VariantSelects extends HTMLElement {
});
}

updateSelectedSwatchValue({ target }) {
updateSelectionMetadata({ target }) {
const { value, tagName } = target;

if (tagName === 'SELECT' && target.selectedOptions.length) {
Array.from(target.options)
.find((option) => option.getAttribute('selected'))
.removeAttribute('selected');
target.selectedOptions[0].setAttribute('selected', 'selected');

const swatchValue = target.selectedOptions[0].dataset.optionSwatchValue;
const selectedDropdownSwatchValue = target
.closest('.product-form__input')
Expand Down Expand Up @@ -1103,16 +1107,8 @@ class VariantSelects extends HTMLElement {
return target.tagName === 'SELECT' ? target.selectedOptions[0] : target;
}

getVariantData(inputId) {
return JSON.parse(this.getVariantDataElement(inputId).textContent);
}

getVariantDataElement(inputId) {
return this.querySelector(`script[type="application/json"][data-resource="${inputId}"]`);
}

get selectedOptionValues() {
return Array.from(this.querySelectorAll('select, fieldset input:checked')).map(
return Array.from(this.querySelectorAll('select option[selected], fieldset input:checked')).map(
({ dataset }) => dataset.optionValueId
);
}
Expand Down
6 changes: 4 additions & 2 deletions assets/media-gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@ if (!customElements.get('media-gallery')) {
activeMedia?.classList?.add('is-active');

if (prepend) {
activeMedia.parentElement.prepend(activeMedia);
activeMedia.parentElement.firstChild !== activeMedia && activeMedia.parentElement.prepend(activeMedia);

if (this.elements.thumbnails) {
const activeThumbnail = this.elements.thumbnails.querySelector(`[data-target="${mediaId}"]`);
activeThumbnail.parentElement.prepend(activeThumbnail);
activeThumbnail.parentElement.firstChild !== activeThumbnail && activeThumbnail.parentElement.prepend(activeThumbnail);
}

if (this.elements.viewer.slider) this.elements.viewer.resetPages();
}

Expand Down
73 changes: 29 additions & 44 deletions assets/product-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,6 @@ if (!customElements.get('product-info')) {
this.postProcessHtmlCallbacks.push((newNode) => {
window?.Shopify?.PaymentButton?.init();
window?.ProductModel?.loadShopifyXR();
publish(PUB_SUB_EVENTS.sectionRefreshed, {
data: {
sectionId: this.sectionId,
resource: {
type: SECTION_REFRESH_RESOURCE_TYPE.product,
id: newNode.dataset.productId,
},
},
});
});
}

Expand All @@ -75,13 +66,16 @@ if (!customElements.get('product-info')) {
this.resetProductFormState();

const productUrl = target.dataset.productUrl || this.pendingRequestUrl || this.dataset.url;
this.pendingRequestUrl = productUrl;
const shouldSwapProduct = this.dataset.url !== productUrl;
const shouldFetchFullPage = !this.isFeaturedProduct && shouldSwapProduct;
const shouldFetchFullPage = this.dataset.updateUrl === 'true' && shouldSwapProduct;

this.renderProductInfo({
requestUrl: this.buildRequestUrlWithParams(productUrl, selectedOptionValues, shouldFetchFullPage),
targetId: target.id,
callback: shouldSwapProduct ? this.handleSwapProduct(productUrl) : this.handleUpdateProductInfo(productUrl),
callback: shouldSwapProduct
? this.handleSwapProduct(productUrl, shouldFetchFullPage)
: this.handleUpdateProductInfo(productUrl),
});
}

Expand All @@ -91,33 +85,27 @@ if (!customElements.get('product-info')) {
productForm?.handleErrorMessage();
}

get isFeaturedProduct() {
return this.dataset.section.includes('featured_product');
}

handleSwapProduct(productUrl) {
handleSwapProduct(productUrl, updateFullPage) {
return (html) => {
this.productModal?.remove();

// Grab the selected variant from the new product info
const variant = this.getSelectedVariant(html.querySelector(`product-info[data-section=${this.sectionId}]`));
const selector = updateFullPage ? "product-info[id^='MainProduct']" : 'product-info';
const variant = this.getSelectedVariant(html.querySelector(selector));
this.updateURL(productUrl, variant?.id);

// If we are in an embedded context (quick add, featured product, etc), only swap product info.
// Otherwise, refresh the entire page content and sibling sections.
if (this.dataset.updateUrl === 'false') {
if (updateFullPage) {
document.querySelector('head title').innerHTML = html.querySelector('head title').innerHTML;

HTMLUpdateUtility.viewTransition(
this,
html.querySelector('product-info'),
document.querySelector('main'),
html.querySelector('main'),
this.preProcessHtmlCallbacks,
this.postProcessHtmlCallbacks
);
} else {
document.querySelector('head title').innerHTML = html.querySelector('head title').innerHTML;

HTMLUpdateUtility.viewTransition(
document.querySelector('main'),
html.querySelector('main'),
this,
html.querySelector('product-info'),
this.preProcessHtmlCallbacks,
this.postProcessHtmlCallbacks
);
Expand All @@ -129,7 +117,6 @@ if (!customElements.get('product-info')) {
this.abortController?.abort();
this.abortController = new AbortController();

this.pendingRequestUrl = requestUrl;
fetch(requestUrl, { signal: this.abortController.signal })
.then((response) => response.text())
.then((responseText) => {
Expand Down Expand Up @@ -170,11 +157,7 @@ if (!customElements.get('product-info')) {
updateOptionValues(html) {
const variantSelects = html.querySelector('variant-selects');
if (variantSelects) {
HTMLUpdateUtility.viewTransition(
this.variantSelectors,
variantSelects,
this.preProcessHtmlCallbacks,
);
HTMLUpdateUtility.viewTransition(this.variantSelectors, variantSelects, this.preProcessHtmlCallbacks);
}
}

Expand Down Expand Up @@ -257,10 +240,13 @@ if (!customElements.get('product-info')) {
}

updateMedia(html, variantFeaturedMediaId) {
if (!variantFeaturedMediaId) return;

const mediaGallerySource = this.querySelector('media-gallery ul');
const mediaGalleryDestination = html.querySelector(`media-gallery ul`);

const refreshSourceData = () => {
if (this.hasAttribute('data-zoom-on-hover')) enableZoomOnHover(2);
const mediaGallerySourceItems = Array.from(mediaGallerySource.querySelectorAll('li[data-media-id]'));
const sourceSet = new Set(mediaGallerySourceItems.map((item) => item.dataset.mediaId));
const sourceMap = new Map(
Expand Down Expand Up @@ -312,18 +298,16 @@ if (!customElements.get('product-info')) {
});
}

if (variantFeaturedMediaId) {
// set featured media as active in the media gallery
this.querySelector(`media-gallery`)?.setActiveMedia?.(
`${this.dataset.section}-${variantFeaturedMediaId}`,
true
);
// set featured media as active in the media gallery
this.querySelector(`media-gallery`)?.setActiveMedia?.(
`${this.dataset.section}-${variantFeaturedMediaId}`,
true
);

// update media modal
const modalContent = this.productModal?.querySelector(`.product-media-modal__content`);
const newModalContent = html.querySelector(`product-modal .product-media-modal__content`);
if (modalContent && newModalContent) modalContent.innerHTML = newModalContent.innerHTML;
}
// update media modal
const modalContent = this.productModal?.querySelector(`.product-media-modal__content`);
const newModalContent = html.querySelector(`product-modal .product-media-modal__content`);
if (modalContent && newModalContent) modalContent.innerHTML = newModalContent.innerHTML;
}

setQuantityBoundries() {
Expand Down Expand Up @@ -367,6 +351,7 @@ if (!customElements.get('product-info')) {
}

updateQuantityRules(sectionId, html) {
if (!this.quantityInput) return;
this.setQuantityBoundries();

const quantityFormUpdated = html.getElementById(`Quantity-Form-${sectionId}`);
Expand Down
Loading

0 comments on commit 0a4e016

Please sign in to comment.