PageSourceSearch

https://www.terranovastyle.com/cdn/shop/t/51/assets/cmp-gift-card-cart.js?v=163340411783324153281780474715

js terranovastyle.com collected 2026-09-26 00:09:31 UTC 19,845 bytes, 45 lines download raw bytes

1class GiftCardCart{constructor(){this.isProcessing=!1,this.lastCartState=null,this.debug=!1,this.originalAddToCart=null,this.mcShopifyIntercepted=!1,this.validationEnabled=this.checkIfValidationEnabled(),this.translations=this.getTranslations(),this.cartCache=null,this.cartCacheTime=0,this.CACHE_TTL=2e3,this.giftCardCache=new Map,console.log("[GiftCardCart] Traduzioni caricate:",{oneGiftCardOnly:this.translations.oneGiftCardOnly,giftCardAlreadyInCart:this.translations.giftCardAlreadyInCart}),this.validationEnabled?this.init():console.log("[GiftCardCart] Validazione Gift Card disabilitata")}getTranslations(){const defaultTranslations={cartConflictTitle:"Attenzione: Gift Card nel carrello",cartConflictMessage:"Le Gift Card devono essere acquistate separatamente dagli altri prodotti. Per procedere con l'ordine, scegli una delle seguenti opzioni:",removeRegularProducts:"Rimuovi i prodotti normali e procedi con le Gift Card",removeGiftCards:"Rimuovi le Gift Card e procedi con gli altri prodotti",cannotAddGiftCard:"Non puoi aggiungere Gift Card quando hai altri prodotti nel carrello",cannotAddRegular:"Non puoi aggiungere prodotti normali quando hai Gift Card nel carrello",oneGiftCardOnly:"\xC8 possibile acquistare solo una Gift Card per ordine",giftCardAlreadyInCart:"Hai gi\xE0 una Gift Card nel carrello",resolveConflict:"Risolvi prima il conflitto nel carrello: le Gift Card devono essere acquistate separatamente",validationFailed:"Le Gift Card devono essere acquistate separatamente",mixedCartWarning:"Attenzione: Le Gift Card non possono essere acquistate insieme ad altri prodotti. Vai al carrello per risolvere il conflitto.",goToCart:"Vai al carrello",close:"Chiudi",completePurchaseFirst:"Completa prima l'acquisto o svuota il carrello",completeGiftCardPurchase:"Completa prima l'acquisto delle Gift Card",resolveConflictBeforeCheckout:"Risolvi il conflitto Gift Card prima di procedere",errorRemovingProducts:"Errore nella rimozione dei prodotti",errorRemovingGiftCards:"Errore nella rimozione delle gift card",productAdded:"Prodotto aggiunto al carrello!",errorAddingToCart:"Errore nell'aggiunta al carrello"};return window.theme&&window.theme.t&&window.theme.t.giftCardValidation?{...defaultTranslations,...window.theme.t.giftCardValidation}:defaultTranslations}init(){this.checkCartOnLoad(),this.interceptMcShopify(),this.interceptFormSubmits(),this.observeCartChanges()}checkIfValidationEnabled(){if(window.theme&&typeof window.theme.giftCardValidation<"u")return window.theme.giftCardValidation;const buyButton=document.querySelector("[data-gift-card-validation]");if(buyButton){const value=buyButton.dataset.giftCardValidation;return value!=="false"&&value!=="0"}return!0}log(message,data=null){this.debug&&console.log(`[GiftCardCart] ${message}`,data||"")}interceptMcShopify(){const checkInterval=setInterval(()=>{window.McShopify&&window.McShopify.addToCart&&!this.mcShopifyIntercepted&&(this.log("McShopify trovato! Intercettazione in corso..."),this.originalAddToCart=window.McShopify.addToCart.bind(window.McShopify),window.McShopify.addToCart=async params=>(this.log("McShopify.addToCart intercettato!",params),await this.validateAddToCart(params)?(this.log("Procedo con aggiunta originale"),this.originalAddToCart(params)):(this.log("Aggiunta bloccata per conflitto Gift Card"),params&&params.onError&&params.onError({message:this.translations.validationFailed,description:this.translations.cartConflictMessage}),Promise.reject("Gift Card validation failed"))),this.mcShopifyIntercepted=!0,clearInterval(checkInterval),this.log("McShopify.addToCart sovrascritto con successo"))},100);setTimeout(()=>clearInterval(checkInterval),1e4)}async validateAddToCart(params){if(!this.checkIfValidationEnabled())return this.log("Validazione disabilitata, permetto aggiunta"),!0;try{const cart=await this.getCart();let isAddingGiftCard=!1,productInfo=null;if(params)if(params.form)productInfo=this.getProductInfoFromDOM(),isAddingGiftCard=this.checkIfGiftCardProduct(productInfo);else if(params.items&&params.items.length>0){const item=params.items[0];window.__cartGiftCarouselAdd?(productInfo={type:"Regular",title:null,handle:null,tags:null},isAddingGiftCard=!1):(productInfo=this.getProductInfoFromDOM(),isAddingGiftCard=this.checkIfGiftCardProduct(productInfo))}else params.formData&&window.__cartGiftCarouselAdd&&(productInfo={type:"Regular",title:null,handle:null,tags:null},isAddingGiftCard=!1);console.log("[GiftCardCart] === VALIDAZIONE ADD TO CART ==="),console.log("[GiftCardCart] Prodotto che si sta aggiungendo:",{isGiftCard:isAddingGiftCard,productInfo});const cartHasGiftCards=this.hasGiftCards(cart),cartHasRegularProducts=this.hasRegularProducts(cart);
1if(console.log("[GiftCardCart] Stato carrello attuale:",{hasGiftCards:cartHasGiftCards,hasRegularProducts:cartHasRegularProducts,itemsCount:cart.items?.length||0}),isAddingGiftCard){if(console.log("[GiftCardCart] Sto aggiungendo una GIFT CARD"),cartHasGiftCards){console.log("[GiftCardCart] BLOCCO: Gift Card gi\xE0 presente nel carrello");const message=this.translations.oneGiftCardOnly||"\xC8 possibile acquistare solo una Gift Card per ordine",subMessage=this.translations.giftCardAlreadyInCart||"Hai gi\xE0 una Gift Card nel carrello";return this.showNotification(`\u274C ${message}. ${subMessage}.`,"error",!1,!0),!1}if(cartHasRegularProducts)return console.log("[GiftCardCart] BLOCCO: Prodotti normali nel carrello, non posso aggiungere Gift Card"),this.showNotification(`\u274C ${this.translations.cannotAddGiftCard}. ${this.translations.completePurchaseFirst}.`,"error",!1,!0),!1}else if(console.log("[GiftCardCart] Sto aggiungendo un PRODOTTO NORMALE"),cartHasGiftCards)return console.log("[GiftCardCart] BLOCCO: Gift Card nel carrello, non posso aggiungere prodotti normali"),this.showNotification(`\u274C ${this.translations.cannotAddRegular}. ${this.translations.completeGiftCardPurchase}.`,"error",!1,!0),!1;return cartHasGiftCards&&cartHasRegularProducts?(this.showNotification(`\u26A0\uFE0F ${this.translations.resolveConflict}`,"warning",!1,!0),!1):!0}catch(error){return console.error("[GiftCardCart] Errore validazione:",error),!0}}getProductInfoFromDOM(){const info={type:null,title:null,handle:null,tags:null},typeElement=document.querySelector('[data-product-type], .product-type, [itemprop="category"]');typeElement&&(info.type=typeElement.dataset?.productType||typeElement.textContent||"");const jsonLd=document.querySelector('script[type="application/ld+json"]');if(jsonLd)try{const data=JSON.parse(jsonLd.textContent);data["@type"]==="Product"&&(info.type=data.category||info.type,info.title=data.name||info.title)}catch{}const titleElement=document.querySelector('h1, .product-title, [itemprop="name"]');titleElement&&(info.title=titleElement.textContent),info.handle=window.location.pathname;const productElement=document.querySelector("[data-product], [data-product-handle], .product");return productElement&&(info.handle=productElement.dataset?.productHandle||info.handle,info.tags=productElement.dataset?.productTags||""),this.log("Info prodotto dal DOM:",info),info}checkIfGiftCardProduct(productInfo){const hasRecipientForm=document.querySelector("recipient-form")!==null;if(hasRecipientForm)return console.log("[GiftCardCart] Rilevato recipient-form - \xC8 una Gift Card"),!0;if(!productInfo)return!1;const checks=[productInfo.type&&productInfo.type.toLowerCase().includes("gift"),productInfo.title&&productInfo.title.toLowerCase().includes("gift"),productInfo.handle&&productInfo.handle.toLowerCase().includes("gift"),productInfo.tags&&productInfo.tags.toLowerCase().includes("gift"),productInfo.type&&productInfo.type.toLowerCase()==="gift card",productInfo.type&&productInfo.type==="Gift Card",productInfo.title&&productInfo.title.toLowerCase().includes("gift card")],isGiftCard=checks.some(check=>check===!0);return console.log("[GiftCardCart] Check Gift Card dettagliato:",{hasRecipientForm,productType:productInfo.type,productTitle:productInfo.title,productHandle:productInfo.handle,productTags:productInfo.tags,checksResults:checks,finalResult:isGiftCard}),isGiftCard}interceptFormSubmits(){document.addEventListener("submit",async e=>{const form=e.target;if(form&&(form.action?.includes("/cart/add")||form.querySelector('[name="add"]'))){this.log("Form submit intercettato:",form.action);const formContainer=form.closest("[data-gift-card-validation]");if(formContainer&&formContainer.dataset.giftCardValidation==="false"){this.log("Validazione disabilitata per questo form");return}if((!window.McShopify||!this.mcShopifyIntercepted)&&(e.preventDefault(),e.stopPropagation(),await this.validateAddToCart({form}))){const formData=new FormData(form);try{(await fetch("/cart/add.js",{method:"POST",body:formData})).ok&&(this.showNotification(`\u2705 ${this.translations.productAdded}`,"success"),setTimeout(()=>{window.location.reload()},1e3))}catch(error){console.error("Errore aggiunta:",error),this.showNotification(this.translations.errorAddingToCart,"error")}}}},!0)}async checkCartOnLoad(){if(!this.isProcessing)try{this.isProcessing=!0;const cart=await this.getCart();this.log("Carrello caricato:",cart);const cartHash=JSON.stringify(cart.items?.map(i=>i.key+i.quantity));if(this.lastCartState===cartHash){this.isProcessing=!1;return}this.lastCartState=cartHash,cart&&cart.items&&cart.items.length>0?this.validateCartAndShowUI(cart):this.removeCartBlockUI()}catch(error){console.error("Errore nel controllo del carrello:",error)}finally{this.isProcessing=!1}}async getCart(forceRefresh=!1){const now=Date.now();if(!forceRefresh&&this.cartCache&&now-this.cartCacheTime<this.CACHE_TTL)return this.cartCache;try{const response=await fetch("/cart.js",{method:"GET",headers:{"Content-Type":"application/json"}});return this.cartCache=await response.json(),this.cartCacheTime=now,this.giftCardCache.clear(),this.cartCache}catch(error){return console.error("Errore nel recupero del carrello:",error),null}}invalidateCache(){this.cartCache=null,this.cartCacheTime=0,this.giftCardCache.clear()}isGiftCard(item){const cacheKey=item.key||item.variant_id;if(cacheKey&&this.giftCardCache.has(cacheKey))return this.giftCardCache.get(cacheKey);const isGift=[item.product_type==="Gift Card",item.product_type==="gift-card",item.product_type==="gift_card",item.product_type==="giftcard",item.product_type&&item.product_type.toLowerCase().includes("gift"),item.handle&&item.handle.includes("gift-card"),item.vendor&&item.vendor.toLowerCase().includes("gift"),item.tags&&item.tags.toLowerCase&&item.tags.toLowerCase().includes("gift"),item.gift_card===!0,item.properties&&item.properties._is_gift==="true",item.properties&&item.properties["Gift card recipient"]==="yes",item.properties&&item.properties["Gift card recipient email"],item.title&&item.title.toLowerCase().includes("gift card")].some(check=>check===!0);return cacheKey&&this.giftCardCache.set(cacheKey,isGift),this.debug&&console.log(`[GiftCardCart] Controllo se "${item.title}" \xE8 una gift card:`,{product_type:item.product_type,risultato:isGift}),isGift}hasGiftCards(cart){return!cart||!cart.items?!1:cart.items.some(item=>this.isGiftCard(item))}hasRegularProducts(cart){return!cart||!cart.items?!1:cart.items.some(item=>!this.isGiftCard(item))}validateCartAndShowUI(cart){if(!this.checkIfValidationEnabled())return this.removeCartBlockUI(),!0;const hasGift=this.hasGiftCards(cart),hasRegular=this.hasRegularProducts(cart);return this.log("Validazione carrello:",{hasGiftCards:hasGift,hasRegularProducts:hasRegular,items:cart.items.map(item=>({title:item.title,type:item.product_type,isGift:this.isGiftCard(item)}))}),hasGift&&hasRegular?(this.showCartBlockUI(cart),!1):(this.removeCartBlockUI(),!0)}showCartBlockUI(cart){const cartForm=document.querySelector("#main-cart-form"),cartContainer=document.querySelector(".main-cart");if(!cartForm&&!cartContainer){this.showMixedCartNotification();return}if(document.getElementById("gift-card-block-message"))return;const blockMessage=document.createElement("div");blockMessage.id="gift-card-block-message",blockMessage.className="alert alert-warning border-warning border-2 my-4",blockMessage.innerHTML=`
2      <div class="d-flex align-items-start gap-3">
3        <svg class="flex-shrink-0" width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
4          <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zM7.002 1.125a6.875 6.875 0 1 1 0 13.75 6.875 6.875 0 0 1 0-13.75zM7.25 4v5.25h1.5V4h-1.5zm0 6.5v1.5h1.5v-1.5h-1.5z"/>
5        </svg>
6        <div class="flex-grow-1">
7          <h5 class="alert-heading mb-2">${this.translations.cartConflictTitle}</h5>
8          <p class="mb-3">${this.translations.cartConflictMessage}</p>
9          
10          <div class="d-flex flex-column flex-sm-row gap-2">
11            <button type="button" class="btn btn-warning" onclick="window.giftCardCart.removeRegularProducts()">
12              ${this.translations.removeRegularProducts}
13            </button>
14            <button type="button" class="btn btn-outline-warning" onclick="window.giftCardCart.removeGiftCards()">
15              ${this.translations.removeGiftCards}
16            </button>
17          </div>
18        </div>
19      </div>
20    `;const cartTitle=document.querySelector(".main-cart h2, .main-cart h1");cartTitle?cartTitle.parentNode.insertBefore(blockMessage,cartTitle.nextSibling):cartContainer&&cartContainer.insertBefore(blockMessage,cartContainer.firstChild),this.disableCheckoutButtons(),this.highlightConflictingItems(cart)}removeCartBlockUI(){const blockMessage=document.getElementById("gift-card-block-message");blockMessage&&blockMessage.remove(),this.enableCheckoutButtons(),this.removeItemHighlights()}disableCheckoutButtons(){document.querySelectorAll('button[type="submit"][name="checkout"], button[name="checkout"], a[href*="/checkout"], .checkout-button, .btn-checkout').forEach(button=>{button.dataset.giftCardDisabled!=="true"&&(button.setAttribute("disabled","disabled"),button.classList.add("disabled","opacity-50"),button.style.pointerEvents="none",button.dataset.giftCardDisabled="true",button.setAttribute("title",this.translations.resolveConflictBeforeCheckout))})}enableCheckoutButtons(){document.querySelectorAll('button[type="submit"][name="checkout"], button[name="checkout"], a[href*="/checkout"], .checkout-button, .btn-checkout').forEach(button=>{button.dataset.giftCardDisabled==="true"&&(button.removeAttribute("disabled"),button.classList.remove("disabled","opacity-50"),button.style.pointerEvents="",button.removeAttribute("title"),button.dataset.giftCardDisabled="false")})}
20highlightConflictingItems(cart){cart.items.forEach((item,index)=>{const itemElement=document.querySelector(`[data-variant-id="${item.variant_id}"]`)||document.querySelector(`[data-product-id="${item.product_id}"]`)||document.querySelectorAll(".cart-item")[index];if(itemElement&&this.isGiftCard(item)){itemElement.classList.add("gift-card-item","border-warning","border-2");const badge=document.createElement("span");badge.className="badge bg-warning text-dark ms-2",badge.textContent="Gift Card";const title=itemElement.querySelector(".cart-item__title, h4, h5");title&&!title.querySelector(".badge")&&title.appendChild(badge)}})}removeItemHighlights(){document.querySelectorAll(".gift-card-item").forEach(item=>{item.classList.remove("gift-card-item","border-warning","border-2")}),document.querySelectorAll(".cart-item .badge").forEach(badge=>{badge.textContent==="Gift Card"&&badge.remove()})}showMixedCartNotification(){this.showNotification(this.translations.mixedCartWarning,"warning",!0,!0)}showNotification(message,type="info",persistent=!1,showCartButton=!1){document.querySelectorAll(".gift-card-notification").forEach(n=>n.remove());const notification=document.createElement("div");notification.className=`gift-card-notification alert alert-${type==="error"?"danger":type} position-fixed start-50 translate-middle-x shadow-lg border-2`,notification.style.cssText="z-index: 99999; min-width: 350px; max-width: 500px; top: 100px; animation: slideDown 0.3s ease-out;";let buttonsHtml="";showCartButton&&(buttonsHtml=`
21        <div class="mt-3 d-flex gap-2">
22          <a href="/cart" class="btn btn-sm btn-${type==="error"?"danger":"warning"}">${this.translations.goToCart}</a>
23          <button type="button" class="btn btn-sm btn-outline-secondary" onclick="this.closest('.gift-card-notification').remove()">${this.translations.close}</button>
24        </div>
25      `),notification.innerHTML=`
26      <div class="d-flex justify-content-between align-items-start">
27        <div class="flex-grow-1">
28          <div class="fw-bold mb-1">${message}</div>
29          ${buttonsHtml}
30        </div>
31        <button type="button" class="btn-close ms-3" aria-label="Close"></button>
32      </div>
33    `;const style=document.createElement("style");style.textContent=`
34      @keyframes slideDown {
35        from {
36          opacity: 0;
37          transform: translateX(-50%) translateY(-20px);
38        }
39        to {
40          opacity: 1;
41          transform: translateX(-50%) translateY(0);
42        }
43      }
44    `,document.querySelector("#gift-card-notification-styles")||(style.id="gift-card-notification-styles",document.head.appendChild(style)),document.body.appendChild(notification),notification.querySelector(".btn-close").addEventListener("click",()=>notification.remove()),setTimeout(()=>{notification.parentNode&&(notification.style.animation="slideDown 0.3s ease-out reverse",setTimeout(()=>notification.remove(),300))},type==="error"?1e4:persistent?15e3:5e3)}async removeGiftCards(){try{const cart=await this.getCart();if(!cart||!cart.items)return;const giftCardItems=cart.items.filter(item=>this.isGiftCard(item));if(this.log("Rimozione gift card:",giftCardItems),giftCardItems.length>0){const updates={};giftCardItems.forEach(item=>{updates[item.key]=0}),this.invalidateCache(),(await fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({updates})})).ok?window.location.reload():this.showNotification(this.translations.errorRemovingGiftCards,"error")}}catch(error){console.error("Errore nella rimozione delle gift card:",error),this.showNotification(this.translations.errorRemovingGiftCards,"error")}}async removeRegularProducts(){try{const cart=await this.getCart();if(!cart||!cart.items)return;const regularItems=cart.items.filter(item=>!this.isGiftCard(item));if(this.log("Rimozione prodotti normali:",regularItems),regularItems.length>0){const updates={};regularItems.forEach(item=>{updates[item.key]=0}),this.invalidateCache(),(await fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({updates})})).ok?window.location.reload():this.showNotification(this.translations.errorRemovingProducts,"error")}}catch(error){console.error("Errore nella rimozione dei prodotti normali:",error),this.showNotification(this.translations.errorRemovingProducts,"error")}}observeCartChanges(){let debounceTimer;const observer=new MutationObserver(()=>{this.isProcessing||(clearTimeout(debounceTimer),debounceTimer=setTimeout(()=>{this.invalidateCache(),this.checkCartOnLoad()},300))}),cartElement=document.querySelector(".main-cart, #main-cart, [data-cart-items]");cartElement&&observer.observe(cartElement,{childList:!0,subtree:!1})}async updateCartCounter(){try{const cart=await this.getCart();document.querySelectorAll(".cart-count, .cart-counter, [data-cart-count]").forEach(counter=>{counter.textContent=cart.item_count||0})}catch(error){console.error("Errore aggiornamento contatore carrello:",error)}}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{window.giftCardCart=new GiftCardCart}):window.giftCardCart=new GiftCardCart,window.GiftCardCart=GiftCardCart;
45//# sourceMappingURL=/cdn/shop/t/51/assets/cmp-gift-card-cart.js.map?v=163340411783324153281780474715

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.