PageSourceSearch

https://www.salondnahair.com/wp-content/plugins/growx-tools/assets/js/call-tracker.js?ver=1.4.48

js salondnahair.com collected 2026-10-09 03:36:59 UTC 7,190 bytes, 197 lines download raw bytes

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.