(async () => { const bodyLabels = document.body.className.match(/\bex-l-\d{4}/g)?.map((key) => key.replace("ex-l-", "")) || []; const addToCartByLabel = {}; const isInCart = !!document.querySelector(".ex-cart"); let currentCpId = generateCpId(); const lineRefInput = !isInCart && createLineRefInput(); if (!isInCart && lineRefInput) lineRefInput.value = `cp_${currentCpId}`; filterBodyLabels(); if (Object.keys(addToCartByLabel).length === 0) return; const currentPageLabelId = document .querySelector(".product-summary.product") ?.className.match(/\blabel_\d{4}/)?.[0] ?.replace("label_", ""); const productWrapper = createHiddenProductWrapper(); const pendingDeleteCpIds = []; const pendingQtyCpIds = new Set(); /* FUNCTIONS */ function generateCpId() { return Math.random().toString(36).slice(2, 8); } function createLineRefInput() { if (!document.querySelector(".ex-product")) return null; const addCartWrapper = document.querySelector(".productaddtocart_container .live-inventory-v2-add-to-cart-wrapper"); const lineRefInput = document.createElement("input"); lineRefInput.type = "hidden"; lineRefInput.name = "lineref"; lineRefInput.id = "lineref"; lineRefInput.classList.add("lineref"); lineRefInput.value = ""; addCartWrapper.append(lineRefInput); return lineRefInput; } function filterBodyLabels() { bodyLabels.forEach((label) => { if (label in addToCartByLabel_original) { const transformed = Object.fromEntries( Object.entries(addToCartByLabel_original[label]).map(([key, value]) => [key, { product_sku: value }]), ); Object.assign(addToCartByLabel, transformed); } }); } function createHiddenProductWrapper() { const productWrapper = document.createElement("div"); productWrapper.classList.add("fetched-product", "hide"); const bodyFooter = document.querySelector("footer.footer"); if (bodyFooter) bodyFooter.append(productWrapper); else document.body.append(productWrapper); return productWrapper; } function createProductObject(scriptElement) { const scriptContent = scriptElement.textContent; const objNameMatch = scriptContent.match(/var\s+(obj_\d+)/); if (!objNameMatch) return; const objName = objNameMatch[1]; if (window[objName] && typeof window[objName] === "object") return; try { const script = document.createElement("script"); script.textContent = scriptContent; document.head.appendChild(script); document.head.removeChild(script); } catch (error) { return; } } function createStyle() { const style = document.createElement("style"); let text = ""; Object.values(addToCartByLabel).forEach((e) => { text = `${text} .minicart .item[data-itemid="${e.product_id}"] .minicart_qty, .item_${e.product_id} .quantity{ pointer-events: none!important; } .minicart .item[data-itemid="${e.product_id}"] .plus-minus, .minicart .item[data-itemid="${e.product_id}"] .delete, .item_${e.product_id} .incr-btn, .item_${e.product_id} .delete-btn { display: none!important; } `; }); style.innerHTML = text; document.head.append(style); } function createItems(domObj) { const createOneItem = (productAddToCart) => { const productButton = productAddToCart.querySelector("button.btn-add-to-cart"); if (!productButton) return; productButton.removeAttribute("disabled"); const productSku = productAddToCart.getAttribute("data-sku") || ""; const objKey = Object.keys(addToCartByLabel).find((k) => addToCartByLabel[k].product_sku === productSku); if (!objKey) return; if (addToCartByLabel[objKey].product_button && addToCartByLabel[objKey].product_input && addToCartByLabel[objKey].product_id) { return; } const productInput = productAddToCart.querySelector("input.inputquantity") || {}; const productId = productAddToCart.getAttribute("data-item-id") || ""; if (!(productButton && productInput && productId)) return; addToCartByLabel[objKey].product_button = productButton; addToCartByLabel[objKey].product_input = productInput; addToCartByLabel[objKey].product_id = productId; const productScript = productAddToCart.querySelector(".buttons.group script"); if (!productScript) return; createProductObject(productScript); productWrapper.append(productAddToCart); productWrapper.classList.add("product-added"); }; let products; if (domObj.querySelector("body.ex-product")) { products = domObj.querySelectorAll(".productaddtocart_container .product"); } if (domObj.querySelector("body.ex-searchresult")) { products = domObj.querySelectorAll(".productsgrid_container .tileparent.product"); } if (!products.length) return; products.forEach((product) => createOneItem(product)); } async function getItemsRequest() { const addCartWrappers = document.querySelectorAll(".ex-product .productaddtocart_container .live-inventory-v2-add-to-cart-wrapper"); const cartDropdownAll = document.querySelector(".cart-dropdown"); const cartItemlistsAll = document.querySelector(".ex-cart .row.main "); const allTobeDisabled = [ ...(addCartWrappers ? [...addCartWrappers] : []), ...(cartDropdownAll ? [cartDropdownAll] : []), ...(cartItemlistsAll ? [cartItemlistsAll] : []), ]; allTobeDisabled.forEach((element) => { element.style.pointerEvents = "none"; element.style.opacity = "0.9"; element.style.filter = "constrast(0.6)"; }); const itemsSku = Object.values(addToCartByLabel).flatMap((innerObj) => Object.values(innerObj)); const querySku = `/search?query=${itemsSku.join("+|")}&p=1`; try { const response = await fetch(`${window.location.origin}${querySku}`); const htmlText = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(htmlText, "text/html"); createItems(doc); } catch (err) { } finally { allTobeDisabled.forEach((element) => { element.style.pointerEvents = ""; element.style.opacity = ""; element.style.filter = ""; }); } } function fireBadgeForCpId(cpId, qty) { if (!lineRefInput || !currentPageLabelId) return; const badge = addToCartByLabel[currentPageLabelId]; if (!badge?.product_button) return; setTimeout(() => { lineRefInput.value = `bg_${cpId}`; badge.product_input.value = qty; badge.product_button.click(); currentCpId = generateCpId(); lineRefInput.value = `cp_${currentCpId}`; }, 100); } function getSurfaceRows(inDropdown) { return inDropdown ? [...document.querySelectorAll(".minicart tr.item")] : [...document.querySelectorAll(".shopping-cart table.items-list tr.item")]; } function setBadgeQtyInDom(badgeIndex, newQty) { [true, false].forEach((inDropdown) => { const row = getSurfaceRows(inDropdown)[badgeIndex]; const valueEl = row?.querySelector(".minicart_qty") || row?.querySelector(".quantity"); if (valueEl && Number(valueEl.value) !== newQty) { valueEl.value = newQty; valueEl.dispatchEvent(new Event("change", { bubbles: true })); } }); } function clickBadgeDeleteInDom(badgeIndex) { [true, false].forEach((inDropdown) => { const row = getSurfaceRows(inDropdown)[badgeIndex]; row?.querySelector(".delete, .delete-btn")?.dispatchEvent(new Event("click", { bubbles: true })); }); } function resolveCpIdFromRow(row) { const inDropdown = !!row.closest(".minicart"); const rowIndex = getSurfaceRows(inDropdown).indexOf(row); if (rowIndex === -1) return null; const entry = $mini_cart[rowIndex]; if (!entry || entry.item_line_ref?.startsWith("bg_")) return null; const cpMatch = entry.item_line_ref?.match(/^cp_(.+)$/); return cpMatch ? cpMatch[1] : null; } const mainAddButton = document.querySelector(".productaddtocart_container .live-inventory-v2-add-to-cart-wrapper button.btn-add-to-cart"); const mainQtyInput = document.querySelector(".productaddtocart_container input.inputquantity"); mainAddButton?.addEventListener( "click", () => { if (!lineRefInput) return; const thisCpId = currentCpId; lineRefInput.value = `cp_${thisCpId}`; const qty = Number(mainQtyInput?.value) || 1; fireBadgeForCpId(thisCpId, qty); }, true, ); document.addEventListener( "click", (e) => { const row = e.target.closest(".minicart tr.item, .shopping-cart table.items-list tr.item"); if (!row) return; const deleteBtn = e.target.closest(".delete, .delete-btn"); if (deleteBtn) { const cpId = resolveCpIdFromRow(row); if (cpId) pendingDeleteCpIds.push(cpId); return; } const qtyBtn = e.target.closest(".plus-minus, .incr-btn"); if (qtyBtn) { const cpId = resolveCpIdFromRow(row); if (cpId) pendingQtyCpIds.add(cpId); } }, true, ); document.addEventListener( "change", (e) => { const qtyInput = e.target.closest(".minicart_qty, .quantity"); if (!qtyInput) return; const row = qtyInput.closest(".minicart tr.item, .shopping-cart table.items-list tr.item"); if (!row) return; const cpId = resolveCpIdFromRow(row); if (cpId) pendingQtyCpIds.add(cpId); }, true, ); document.addEventListener("cart-total-update", (e) => { const { type } = e.detail; if (type === "update-quantity") { pendingQtyCpIds.forEach((cpId) => { const mainEntry = $mini_cart.find((en) => en.item_line_ref === `cp_${cpId}`); if (!mainEntry) { pendingQtyCpIds.delete(cpId); return; } const badgeIndex = $mini_cart.findIndex((en) => en.item_line_ref === `bg_${cpId}`); if (badgeIndex === -1) return; setBadgeQtyInDom(badgeIndex, mainEntry.item_order_qty); pendingQtyCpIds.delete(cpId); }); } else if (type === "remove-item") { if (!pendingDeleteCpIds.length) return; const cpId = pendingDeleteCpIds.shift(); const badgeIndex = $mini_cart.findIndex((en) => en.item_line_ref === `bg_${cpId}`); if (badgeIndex === -1) return; clickBadgeDeleteInDom(badgeIndex); } }); await getItemsRequest(); createStyle(); })();