1/** 2 * GrowX Tools - Call Tracking Script 3 */ 4 5/* âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 6 * UTM Cookie Persistence 7 * Reads UTM parameters from the current URL and stores them in 8 * 30-day cookies named gxt_utm_{param}. This way, if the user 9 * navigates to another page before submitting a form, the PHP 10 * class GXT_Helpers::get_utm() can still read them from cookies. 11 * âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 12(function() { 13 var utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; 14 var url = new URLSearchParams(window.location.search); 15 var expires = new Date(); 16 expires.setDate(expires.getDate() + 30); 17 var exp = '; expires=' + expires.toUTCString() + '; path=/; SameSite=Lax'; 18 19 utmParams.forEach(function(param) { 20 var val = url.get(param); 21 if (val) { 22 document.cookie = 'gxt_' + param + '=' + encodeURIComponent(val) + exp; 23 } 24 }); 25})(); 26 27(function($) { 28 'use strict'; 29 30 // Get settings from localized script 31 var settings = window.atpSettings || {}; 32 33 // Debug function 34 function debug(message, data) { 35 if (settings.debug === '1') { 36 console.log('[ATP Call Tracker]', message, data || ''); 37 } 38 } 39 40 // Get device type 41 function getDeviceType() { 42 var ua = navigator.userAgent; 43 if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) { 44 return 'tablet'; 45 } 46 if (/Mobile|iP(hone|od)|Android|BlackBerry|IEMobile|Kindle/.test(ua)) { 47 return 'mobile'; 48 } 49 return 'desktop'; 50 } 51 52 // Get browser name 53 function getBrowser() { 54 var ua = navigator.userAgent; 55 if (ua.indexOf('Firefox') > -1) return 'Firefox'; 56 if (ua.indexOf('Chrome') > -1) return 'Chrome'; 57 if (ua.indexOf('Safari') > -1) return 'Safari'; 58 if (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident') > -1) return 'IE'; 59 if (ua.indexOf('Edge') > -1) return 'Edge'; 60 return 'Unknown'; 61 } 62 63 // Get UTM parameters 64 function getUTMParams() { 65 var params = new URLSearchParams(window.location.search); 66 return { 67 utm_source: params.get('utm_source') || '', 68 utm_medium: params.get('utm_medium') || '', 69 utm_campaign: params.get('utm_campaign') || '' 70 }; 71 } 72 73 // Track call click 74 function trackCall(phoneNumber, linkText, callType) { 75 var utmParams = getUTMParams(); 76 77 var data = { 78 action: 'atp_track_call', 79 nonce: settings.nonce, 80 phone_number: phoneNumber, 81 link_text: linkText, 82 page_url: window.location.href, 83 page_title: document.title, 84 device_type: getDeviceType(), 85 browser: getBrowser(), 86 referrer: document.referrer, 87 utm_source: utmParams.utm_source, 88 utm_medium: utmParams.utm_medium, 89 utm_campaign: utmParams.utm_campaign, 90 call_type: callType, 91 session_id: getSessionId() 92 }; 93 94 debug('Tracking call', data); 95 96 // Send to backend 97 $.ajax({ 98 url: settings.ajaxUrl, 99 type: 'POST', 100 data: data, 101 success: function(response) { 102 debug('Call tracked successfully', response); 103 }, 104 error: function(error) { 105 debug('Error tracking call', error); 106 } 107 }); 108 109 // Send to Google Analytics if available 110 if (typeof gtag !== 'undefined' && settings.eventCategory) { 111 gtag('event', settings.eventAction, { 112 event_category: settings.eventCategory, 113 event_label: phoneNumber, 114 phone_number: phoneNumber, 115 call_type: callType, 116 page_url: window.location.href 117 }); 118 debug('Sent to Google Analytics'); 119 } else if (typeof ga !== 'undefined' && settings.eventCategory) { 120 ga('send', 'event', settings.eventCategory, settings.eventAction, phoneNumber); 121 debug('Sent to Google Analytics (Universal)'); 122 } 123 } 124 125 // Get or create session ID 126 function getSessionId() { 127 var sessionId = getCookie('atp_session'); 128 if (!sessionId) { 129 sessionId = 'sess_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
130 setCookie('atp_session', sessionId, 30); 131 } 132 return sessionId; 133 } 134 135 // Cookie helpers 136 function setCookie(name, value, days) { 137 var expires = ''; 138 if (days) { 139 var date = new Date(); 140 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 141 expires = '; expires=' + date.toUTCString(); 142 } 143 document.cookie = name + '=' + (value || '') + expires + '; path=/'; 144 } 145 146 function getCookie(name) { 147 var nameEQ = name + '='; 148 var ca = document.cookie.split(';'); 149 for (var i = 0; i < ca.length; i++) { 150 var c = ca[i]; 151 while (c.charAt(0) === ' ') c = c.substring(1, c.length); 152 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 153 } 154 return null; 155 } 156 157 // Initialize tracking when DOM is ready 158 $(document).ready(function() { 159 debug('Call tracker initialized', settings); 160 161 // Track phone links 162 $(document).on('click', settings.phoneSelector || 'a[href^="tel:"]', function(e) { 163 var $link = $(this); 164 var href = $link.attr('href'); 165 var phoneNumber = href.replace('tel:', ''); 166 var linkText = $link.text().trim(); 167 168 trackCall(phoneNumber, linkText, 'phone'); 169 }); 170 171 // Track WhatsApp if enabled 172 if (settings.trackWhatsApp === '1') { 173 $(document).on('click', 'a[href*="wa.me"], a[href*="api.whatsapp.com"]', function(e) { 174 var $link = $(this); 175 var href = $link.attr('href'); 176 var phoneMatch = href.match(/\d+/); 177 var phoneNumber = phoneMatch ? phoneMatch[0] : 'unknown'; 178 var linkText = $link.text().trim(); 179 180 trackCall(phoneNumber, linkText, 'whatsapp'); 181 }); 182 } 183 184 // Track SMS if enabled 185 if (settings.trackSMS === '1') { 186 $(document).on('click', 'a[href^="sms:"]', function(e) { 187 var $link = $(this); 188 var href = $link.attr('href'); 189 var phoneNumber = href.replace('sms:', '').split('?')[0]; 190 var linkText = $link.text().trim(); 191 192 trackCall(phoneNumber, linkText, 'sms'); 193 }); 194 } 195 }); 196 197})(jQuery);
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.