// JavaScript Document //////////////////////////////////////// // HERING ///////////////////////////// // Last Check: 19-12-2025 10:00:00h // ///////////////////////////////////// oppuz.attach({ ...Object.fromEntries(new URLSearchParams(URL.parse(document.currentScript.src).hash.replace("#", '?'))), deps: [ "navigation" ], get _navigation() { return this.$.getModule("navigation") }, listenDataLayer(listener) { const onDataLayer = listener.onDataLayer.bind(listener) const debugLog = this.$.debug.bind(this.$) // window.dataLayer = window.dataLayer || [] const oldPush = window.dataLayer.push; window.dataLayer.push = (function (...args) { for (const arg of args) { try { onDataLayer(arg) } catch (e) { // this.$.debug("error", e) debugLog("error", e) // } } oldPush.call(this, ...args); }) for (const arg of new Array(...window.dataLayer)) { try { onDataLayer(arg) } catch (e) { this.$.debug("error", e) } } }, // Fn Auxiliar USER_DATA // Revised Fn Auxiliar USER_DATA - validateEmail(emv:String) validateEmail(emv) { this.$.debug("Oppp::validateEmail -> Started | raw: " + emv); if (typeof emv !== "string") { this.$.debug("Oppp::validateEmail -> Input is NOT string"); return "invalid"; } emv = emv.trim(); if (!emv) { this.$.debug("Oppp::validateEmail -> Empty string"); return "invalid"; } const parts = emv.split('@'); const vld1 = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(emv); const vld2 = parts.length === 2 && !emv.includes('..'); const vld3 = emv.charAt(0) !== '.' && parts[0] !== '.'; if (vld1 && vld2 && vld3) { this.$.debug("Oppp::validateEmail -> OK: " + emv); return emv; } this.$.debug("Oppp::validateEmail -> INVALID: " + emv); return "invalid"; }, // Revised Auxiliar fn : getUserData(email:ElmHTML, firstName:ElmHTML, lastName:ElmHTML) getUserData(fld1, fld2, fld3) { this.$.debug("Oppp::getUserData -> Started"); // --- 1) Validar campo de email ----------------------------- if (!fld1 || typeof fld1.value !== "string") { this.$.debug("Oppp::getUserData -> fld1 inválido ou sem .value"); return undefined; } const emailRaw = fld1.value.trim(); const validEmail = this.validateEmail(emailRaw); if (validEmail === "invalid") { this.$.debug("Oppp::getUserData -> Email inválido, abortando"); return undefined; } // --- 2) Montar Nome (opcional) ----------------------------- let fn = "", ln = ""; if (fld2 && typeof fld2.value === "string") fn = fld2.value.trim(); if (fld3 && typeof fld3.value === "string") ln = fld3.value.trim(); const name = [fn, ln].filter(Boolean).join(" "); // --- 3) Retorno Final -------------------------------------- const userData = name ? { email: validEmail, name: name } : { email: validEmail }; this.$.debug("Oppp::getUserData -> OK:", userData); return userData; }, // Fn Auxiliar loginCode() { this.$.debug("Oppp::loginCode is On --> Started"); const self = this; // evita registrar o delegado mais de uma vez if (this._loginCodeDelegated) { this.$.debug("Oppp::loginCode -> delegado já registrado, saindo"); return; } this._loginCodeDelegated = true; // delegação global: funciona mesmo que o botão seja recriado várias vezes document.addEventListener('click', function (e) { const bt = e.target.closest('div.vtex-login-2-x-sendButton > button'); if (!bt) return; // clique não foi no botão ENVIAR let em = document.querySelector('input.vtex-styleguide-9-x-input'); let fn = undefined; let ln = undefined; let fm = em ? em.closest('form') : null; self.$.debug("Oppp::loginCode -> CLICK delegado no botão de código"); // Se quiser segurar o submit pra garantir captura de dados antes: // e.preventDefault(); try { // aqui entra sua coleta de dados real self.oppuzUserData3(em, bt, fn, ln); self.$.debug("Oppp::loginCode is On --> bt CLICK (delegated)"); } catch (err) { console.error("Oppp::loginCode -> erro em oppuzUserData3:", err); } // Se usou preventDefault e quiser submeter depois: // if (fm) fm.submit(); }); setTimeout(() => { const bts = document.querySelector('div.vtex-login-2-x-emailPasswordOptionBtn'); if (bts) { bts.addEventListener('click', () => { this.loginPassword(); }); this.$.debug("Oppp::loginPassword was set"); } }, 3000); }, // 'vtex-login-2-x-button' 'vtex-login-2-x-accessCodeOptionBtn' // 'vtex-login-2-x-button' 'vtex-login-2-x-emailPasswordOptionBtn' // Fn Auxiliar loginPassword() { this.$.debug("Oppp::loginPassword is On-> Started"); const bind = () => { let em = document.querySelector('input.vtex-styleguide-9-x-input'); let bt = document.querySelector('div.vtex-login-2-x-sendButton > button.vtex-button'); let fn = undefined; let ln = undefined; let fm = em ? em.closest('form') : null; if (!em || !bt) { return false; // ainda não carregou } this.oppuzUserData(em, bt, fn, ln); //(email, button, firstName, lastName); return true; }; // tenta imediatamente if (bind()) return; // MutationObserver de fallback const observer = new MutationObserver(() => { if (bind()) { observer.disconnect(); this.$.debug("Oppp::loginPassword -> bound via MutationObserver"); } }); observer.observe(document.body, { childList: true, subtree: true }); }, // Fn Auxiliar loginMainBar() { this.$.debug("Oppp::USER_DATA > Btn Login MainBar"); // tentativa imediata (código original) let ic = document.querySelector('use[href*="#Login"]'); let ica = ic ? ic.closest('a') : null; if (ica) { ica.addEventListener('click', () => { this.openVtexModal(); }); return; // se já encontrou, para aqui } // fallback com MutationObserver (mínima alteração) const observer = new MutationObserver(() => { ic = document.querySelector('use[href*="#Login"]'); ica = ic ? ic.closest('a') : null; if (ica) { ica.addEventListener('click', () => { this.openVtexModal(); }); observer.disconnect(); this.$.debug("Oppp::USER_DATA > Btn Login MainBar bound via observer"); } }); observer.observe(document.body, { childList: true, subtree: true }); }, // Fn Auxiliar loginNewsletter() { // Btn Newsletter this.$.debug("Oppp::USER_DATA > Btn Login Newsletter"); let fm = document.querySelector('form[hx-target="#newsletter"]'); let em = fm.querySelector('div div input[name="email"]'); let bt = fm.querySelector('div div button'); let fn = fm.querySelector('div div input[name="name"]'); let ln = undefined; this.oppuzUserData(em,bt,fn,ln); //oppuzUserData(email, button, firstName, lastName) }, // Fn Auxiliar getProductImageUrl(evento){ this.$.debug("Oppp::getProductImageUrl is On --> "); const url = window.location.href; var g = url.split('-'); var i = g[g.length-2].replace(/[^0-9]/g, ''); var j = g[g.length-1].replace(/[^0-9]/g, ''); var h = i + "_" + j; const prdId = h; const imgRgx = new RegExp(`${prdId}_(\\d+)`); const imgSet = new Set(); // Set evita repetições document.querySelectorAll('img').forEach(img => { const src = img.getAttribute('src'); if (src && imgRgx.test(src)) { imgSet.add(src); // Set só guarda valores únicos } }); const imgsPrd = Array.from(imgSet); imgsPrd.sort((a, b) => { const numA = parseInt(a.match(imgRgx)[1]); const numB = parseInt(b.match(imgRgx)[1]); return numA - numB; }); const img1 = imgsPrd[0]; this.$.debug("Oppp::ImageUrl-> " + img1); return img1; }, // Fn Auxiliar getCategoryFromEvent(evento){ var ev = evento; // evento do DL passado por parâmetro na fn() var ec = ev.ecommerce; var ct = ec.product[0].category[0].replaceAll('/','') var act = []; act.push(ct); return act; }, // Fn Auxiliar getCategoryFromUrl(urlp) { var ce = urlp; var or = window.location.origin; var pn = ce.replace(or, ''); var ap = []; if(pn[0] =="/"){ap = pn.slice(1).split("/")} return ap; }, // Fn Auxiliar getCategoryFromItemView(evento){ var ev = evento; // evento do DL passado por parâmetro na fn() var ec = ev.ecommerce; var it = ec.items[0] var cn = it.item_category2; var pc = it.item_category; var ce = window.location.href; var ap = []; ap[0] = pc; ap[1] = cn; return ap; }, // Fn Auxiliar getCategoryFromBreadcrumb(evento){ const bcrumbs = Array.from(document.querySelectorAll('ul')).find(ul => { const lnks = ul.querySelectorAll('li a'); const txcont = Array.from(lnks, a => a.textContent.trim().toLowerCase()); return ul.offsetParent !== null && txcont.includes("home") && lnks.length >= 2; })?.querySelectorAll('li a'); var bcrumbstx = bcrumbs ? Array.from(bcrumbs, a => a.textContent.trim()) : []; bcrumbstx.shift(); bcrumbstx = bcrumbstx.map(txt => txt.replace(/\s*\([^)]*\)/g, '').trim()); return bcrumbstx; }, // Fn Auxiliar buildCategoryTree(app){ var ap = app; var ac = ""; var an = ""; var obj = {}; var cat = []; for (var i = 0; i < ap.length; i++) { ac += "/" + ap[i]; an += (an ? " " : "") + ap[i]; obj = {id: ac, name:an} cat.push(obj); } return cat; }, getSkuPdp(){ var evt = dataLayer.filter( (item) => { return item.region=== 'PDP'; }).pop(); // Pega o ultimo item var skuObj = evt.skuStocks var aSku = Object.keys(skuObj).filter(key => skuObj[key] > 0) return aSku; }, getEvent(eventName){ var evt = dataLayer.filter( (item) => { return item.event === eventName; }).pop(); // Pega o último item return evt; }, // Encontra o