1/** 2 * google-onetap-capture â helper dùng chung. 3 * 4 * Nạp Äầu tiên. Tạo namespace window.GOT cho phone-popup.js và onetap.js dùng. 5 * Cấu hình Äến từ window.GOT_CFG do PHP in ra â xem includes/class-got-frontend.php. 6 */ 7(function (w) { 8 'use strict'; 9 10 var cfg = w.GOT_CFG || {}; 11 12 var STORE_KEY = 'got_user'; 13 var OPTOUT = 'got_optout'; // cookie cÅ© cá»§a bản â¤1.4.1, nay chá» Äá» dá»n Äi 14 var LATER = 'got_phone_later'; // Äã há»i SÄT rá»i -> nghá» cfg.dismissDays ngà y 15 16 /* ---------- Nháºn diá»n Äã lưu á» máy ---------- */ 17 18 function getUser() { try { return JSON.parse(localStorage.getItem(STORE_KEY)); } catch (e) { return null; } } 19 function setUser(u) { try { localStorage.setItem(STORE_KEY, JSON.stringify(u)); } catch (e) {} } 20 function forgetUser(){ try { localStorage.removeItem(STORE_KEY); } catch (e) {} } 21 22 /* ---------- Cookie ---------- */ 23 24 function getCookie(name) { 25 var v = '; ' + document.cookie; 26 var parts = v.split('; ' + name + '='); 27 if (parts.length === 2) return parts.pop().split(';').shift(); 28 return ''; 29 } 30 31 // Dùng cookie chứ không dùng localStorage: chÃnh localStorage là thứ vừa bá» xoá khi bấm X 32 function setCookie(name, days) { 33 // days = 0 -> cookie theo phiên (Äóng trình duyá»t là hết) 34 var age = days > 0 ? ';max-age=' + (days * 86400) : ''; 35 document.cookie = name + '=1;path=/' + age + ';SameSite=Lax'; 36 } 37 38 function delCookie(name) { 39 document.cookie = name + '=;path=/;max-age=0;SameSite=Lax'; 40 } 41 42 function ss(k) { try { return sessionStorage.getItem(k) || ''; } catch (e) { return ''; } } 43 44 /* ---------- UTM ---------- */ 45 46 var UTM_KEY = 'got_utm'; 47 var UTM_FIELDS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term']; 48 49 function readUtm() { try { return JSON.parse(sessionStorage.getItem(UTM_KEY)) || null; } catch (e) { return null; } } 50 function saveUtm(o) { try { sessionStorage.setItem(UTM_KEY, JSON.stringify(o)); } catch (e) {} } 51 52 /** 53 * Tá»± thu UTM, KHÃNG phụ thuá»c tracking_source_optimized.js â script Äó không 54 * ÄÆ°á»£c plugin nà o enqueue, trên production nó và o qua GTM nên có thá» vắng mặt. 55 * Chá»t và o sessionStorage ngay trang Äầu Äá» còn nguyên khi user submit á» trang khác. 56 */ 57 function captureUtm() { 58 var qs = null; 59 try { qs = new URLSearchParams(location.search); } catch (e) {} 60 61 if (qs) { 62 var found = {}, has = false; 63 UTM_FIELDS.forEach(function (k) { 64 var v = qs.get(k); 65 if (v) { found[k] = v; has = true; } 66 }); 67 if (has) { // URL có UTM -> ưu tiên tuyá»t Äá»i, ghi Äè cái cÅ© 68 found.landing_url = location.href; 69 saveUtm(found); 70 return found; 71 } 72 } 73 74 var stored = readUtm(); 75 if (stored) return stored; // Äã chá»t từ trang trưá»c trong cùng phiên 76 77 // Chưa có gì: mượn giá trá» cá»§a script tracking dùng chung, nếu nó Äang chạy. 78 // Là m váºy Äá» khá»p Äúng cách phân loại cá»§a pipeline CRM hiá»n có. 79 var shared = {}, got = false; 80 UTM_FIELDS.forEach(function (k) { 81 var v = ss(k); 82 if (v) { shared[k] = v; got = true; } 83 }); 84 if (got) { shared.landing_url = location.href; saveUtm(shared); return shared; } 85 86 // Không có script Äó -> tá»± phân loại tá»i giản theo referrer 87 var out = { utm_source: 'direct', utm_medium: 'typed', landing_url: location.href }; 88 var ref = document.referrer || ''; 89 if (ref) { 90 try { 91 var rh = new URL(ref).hostname.replace(/^www\./, ''); 92 if (rh !== location.hostname.replace(/^www\./, '')) { 93 if (/(google|bing|yahoo|duckduckgo|coccoc|baidu|yandex|naver|ecosia)\./.test(rh)) { 94 out.utm_source = 'organic'; out.utm_medium = rh; 95 } else { 96 out.utm_source = rh; out.utm_medium = 'referral'; 97 } 98 } 99 } catch (e) {} 100 } 101 saveUtm(out); 102 return out; 103 } 104 105 /** 106 * Ngữ cảnh gá»i kèm SÄT: cookie_id Äá» CDP ná»i vá»i lá»ch sá» duyá»t web ẩn danh, 107 * utm_* lấy từ captureUtm(). 108 */ 109 function context() { 110 var uid = getCookie('_asm_uid'); 111 if (!uid) { try { uid = localStorage.getItem('_asm_uid') || ''; } catch (e) { uid = ''; } } 112 113 var t = captureUtm(); 114 return { 115 cookie_id: uid, 116 page_url: location.href, 117 landing_url: t.landing_url || location.href, 118 page_title: document.title, 119 utm_source: t.utm_source || '', 120 utm_medium: t.utm_medium || '', 121 utm_campaign: t.utm_campaign || '',
122 utm_content: t.utm_content || '', 123 utm_term: t.utm_term || '' 124 }; 125 } 126 127 /* ---------- SÄT ---------- */ 128 129 /** 130 * Má»t thông báo dùng chung cho má»i kiá»u sai. Sá»a á» Cà i Äặt â Popup thu sá» 131 * Äiá»n thoại â Báo lá»i SÄT (khoá cfg.phoneError). 132 */ 133 function phoneError() { 134 return cfg.phoneError || 'Sá» Äiá»n thoại không hợp lá», vui lòng nháºp lại'; 135 } 136 137 /** 138 * Chuẩn hoá + kiá»m tra SÄT, trả vá» cả Là DO sai Äá» hiá»n ra cho user. 139 * 140 * Vì SÄT ghi-má»t-lần, gõ nhầm là há»ng vÄ©nh viá» n và không ai phát hiá»n ra â 141 * nên phải chặn ngay lúc nháºp, và phải nói rõ sai chá» nà o. 142 * 143 * Quy tắc PHẢI khá»p GOT_Payload::phone() bên PHP: lá»ch nhau thì user thấy 144 * "Äã ghi nháºn" nhưng server lại từ chá»i, mà luá»ng Äó không báo lá»i. 145 * Không lá»c theo Äầu sá» nhà mạng â Äầu sá» má»i ra sẽ chặn nhầm khách tháºt. 146 */ 147 function checkPhone(v) { 148 // `code` giữ lại Äá» test và gỡ lá»i biết sai kiá»u gì; user chá» thấy má»t câu. 149 var fail = function (code) { return { ok: false, code: code, msg: phoneError(), value: '' }; }; 150 151 var raw = (v || '').trim(); 152 if (!raw) return fail('empty'); 153 154 var d = raw.replace(/\D+/g, ''); 155 if (!d) return fail('nodigit'); 156 157 if (d.indexOf('00') === 0) d = d.slice(2); // 00 = tiá»n tá» quá»c tế cÅ© 158 if (d.indexOf('84') === 0 && d.length >= 11) d = '0' + d.slice(2); // +84 -> 0 159 if (d.charAt(0) !== '0') d = '0' + d; 160 161 if (d.length === 10) return { ok: true, code: 'ok', msg: '', value: d }; 162 163 return fail(d.length < 10 ? 'short' : 'long'); 164 } 165 166 /** Giữ cho chá» nà o chá» cần biết hợp lá» hay không. */ 167 function validPhone(v) { 168 return checkPhone(v).value; 169 } 170 171 /* ---------- Thông báo ná»i ---------- */ 172 173 // Style á» assets/css/onetap.css (.got-toast) 174 function toast(msg) { 175 var t = document.createElement('div'); 176 t.className = 'got-toast'; 177 t.textContent = msg; 178 document.body.appendChild(t); 179 setTimeout(function () { 180 t.classList.add('got-toast--out'); 181 setTimeout(function () { if (t.parentNode) t.parentNode.removeChild(t); }, 400); 182 }, 2600); 183 } 184 185 w.GOT = { 186 cfg: cfg, 187 STORE_KEY: STORE_KEY, OPTOUT: OPTOUT, LATER: LATER, 188 getUser: getUser, setUser: setUser, forgetUser: forgetUser, 189 getCookie: getCookie, setCookie: setCookie, delCookie: delCookie, 190 ss: ss, captureUtm: captureUtm, context: context, 191 checkPhone: checkPhone, validPhone: validPhone, toast: toast 192 }; 193})(window);
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.