/* (c) Trove Purpose: Primary JS file to support core Trove features within the theme app extension */ (async function () { /* Retrieve the theme customizer settings from the Core Features block */ const coreConfigElem = document.querySelector(".r-core-config"); const coreConfig = coreConfigElem ? JSON.parse(coreConfigElem.textContent) : null; /* Function to inspect the page for markup where we need to render a "buy used" button based on a given product ID */ const buyButton = async () => { /* look through markup and find our special tags that need to be processed */ document.querySelectorAll(".rec-buy-used").forEach(async (btnContainer) => { const buyUsedButton = btnContainer.querySelector(".rec-buy-used-button"); if (!buyUsedButton) { return false; } const productId = buyUsedButton.getAttribute("data-product-id"); const variantId = buyUsedButton.getAttribute("data-variant-id"); if (!productId) { return false; } /* we have a product, go see if it has any used listings */ try { const buyUsedFetch = await fetch( `${coreConfig.app_proxy_path}/buyer/product-lookup/${productId}/${ variantId || "" }` ); const buyUsedData = await buyUsedFetch.json(); /* we have data, render the information */ if (!buyUsedData.errors && buyUsedData.data?.count > 0) { let buyUsedButtonContent = buyUsedButton.innerHTML; buyUsedButtonContent = buyUsedButtonContent.replace( "%count%", buyUsedData.data?.count ); buyUsedButtonContent = buyUsedButtonContent.replace( "%price_low%", buyUsedData.data?.lowest_price ); buyUsedButtonContent = buyUsedButtonContent.replace( "%price_high%", buyUsedData.data?.highest_price ); buyUsedButtonContent = buyUsedButtonContent.replace( "%item%", buyUsedData.data?.count != 1 ? buyUsedButton.getAttribute("data-plural") : buyUsedButton.getAttribute("data-singular") ); buyUsedButton.href = variantId ? buyUsedData.data?.product_handle : buyUsedData.data?.product_handle.split("?")[0]; buyUsedButton.innerHTML = buyUsedButtonContent; btnContainer.style.display = "block"; } } catch (err) { console.error("buyButton", error); } }); }; /* Function to handle the removal of a special prefix or suffix from product titles around the buyer experience */ const titleTokenRemove = async () => { /* proceed if we have necessary configuration */ if (coreConfig) { try { if (coreConfig.block_settings.title_token?.length > 0) { const nodeAdjust = (selector) => { document.querySelectorAll(selector).forEach((node) => { const nodeLookup = new RegExp( coreConfig.block_settings.title_token, "i" ); const newHTML = node.innerHTML.replace(nodeLookup, ""); node.innerHTML = newHTML; }); }; /* we have a title token, now go through each possible selector where a title can exist and remove this token */ nodeAdjust(".r-app-wrap .r-pdp-title-heading"); nodeAdjust(".r-app-wrap .r-pdp-var-modal-title h1"); nodeAdjust(".r-app-wrap .r-product-card-title h3"); } } catch (e) { console.log("r-badge-expose-problem"); } } }; /* Logic to apply first/last classes on spacing blocks within spacing regions */ const blockSpacing = () => { document .querySelectorAll(".r-block-spacing-container") .forEach((spacing) => { const spacingElems = spacing.querySelectorAll(".r-block-spacing"); if (spacingElems.length > 1) { spacingElems[0].classList.add("r-block-spacing-first"); spacingElems[spacingElems.length - 1].classList.add( "r-block-spacing-last" ); } }); }; /* Function to apply our other functions */ const processCoreFunctions = () => { blockSpacing(); titleTokenRemove(); buyButton(); }; processCoreFunctions(); document.addEventListener("rec-content-ready", processCoreFunctions); document.addEventListener("rec-plp-appended", processCoreFunctions); document.addEventListener("rec-plp-paged", processCoreFunctions); })();