1/** 2 * Insurance Popup Analytics Tracking 3 * Captures 7 core events for insurance popup analytics 4 * Supports both auto-fire and manual triggers with regular/shine popup types 5 * Version: 1.0.7 - Removed nonce verification for simplified analytics tracking 6 */ 7 8(function($) { 9 'use strict'; 10 11 // Safety check: Ensure we don't have any conflicts with old scripts 12 if (typeof sbr_ajax !== 'undefined') { 13 console.warn('Insurance Popup Tracker: Found old sbr_ajax variable, ignoring it.'); 14 } 15 16 console.log('Insurance Popup Tracker: Script loaded v1.0.1'); 17 18 // Global tracking state 19 window.InsurancePopupTracker = { 20 sessionId: null, 21 trackingEnabled: true, 22 baseUrl: null, 23 currentPageUrl: window.location.href, 24 currentPageId: null, 25 26 // Initialize tracking system 27 init: function() { 28 console.log('Insurance Popup Tracker: Initializing...'); 29 30 // Set up AJAX variables 31 if (typeof insurance_analytics !== 'undefined') { 32 console.log('Insurance Popup Tracker: Found insurance_analytics variables'); 33 this.baseUrl = insurance_analytics.ajax_url; 34 this.currentPageId = insurance_analytics.page_id; 35 this.currentPageUrl = insurance_analytics.page_url || window.location.href; 36 } else { 37 console.error('Insurance Popup Tracker: insurance_analytics variables not found. Tracking disabled.'); 38 this.trackingEnabled = false; 39 return; 40 } 41 42 this.generateSessionId(); 43 this.getCurrentPageId(); 44 this.setupEventListeners(); 45 console.log('Insurance Popup Tracker: Initialized successfully'); 46 }, 47 48 // Generate unique session ID for tracking (with persistence) 49 generateSessionId: function() { 50 // Try to get existing session ID from cookie first 51 var existingSessionId = this.getCookie('insurance_popup_session_id'); 52 if (existingSessionId) { 53 this.sessionId = existingSessionId; 54 console.log('Insurance Popup Tracker: Using existing session ID:', this.sessionId); 55 } else { 56 // Generate new session ID and store it 57 this.sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); 58 this.setCookie('insurance_popup_session_id', this.sessionId, 1); // Store for 1 day 59 console.log('Insurance Popup Tracker: Generated new session ID:', this.sessionId); 60 } 61 }, 62 63 // Get current page ID from WordPress 64 getCurrentPageId: function() { 65 // Use from localized variables if available 66 if (this.currentPageId) { 67 return; 68 } 69 70 // Try to get from global WordPress variables 71 if (typeof woocommerce_params !== 'undefined' && woocommerce_params.page_id) { 72 this.currentPageId = woocommerce_params.page_id; 73 } else if (typeof sbr_page_id !== 'undefined') { 74 this.currentPageId = sbr_page_id; 75 } else { 76 // Fallback to extracting from URL or body class 77 var bodyClasses = document.body.className; 78 var pageIdMatch = bodyClasses.match(/page-id-(\d+)/); 79 if (pageIdMatch) { 80 this.currentPageId = pageIdMatch[1]; 81 } else { 82 this.currentPageId = 0; // Default fallback 83 } 84 } 85 }, 86 87 // Setup event listeners for popup tracking (DISABLED - using direct calls only) 88 setupEventListeners: function() { 89 // Event listeners disabled to prevent conflicts with direct tracking calls 90 // All tracking is now done via direct trackEvent() calls from the popup code 91 console.log('Insurance Popup Tracker: Event listeners disabled - using direct calls only'); 92 93 // Keeping MutationObserver for true auto-detection only 94 var self = this; 95 if (typeof MutationObserver !== 'undefined') { 96 var observer = new MutationObserver(function(mutations) { 97 mutations.forEach(function(mutation) { 98 if (mutation.type === 'childList') {
99 mutation.addedNodes.forEach(function(node) { 100 if (node.nodeType === Node.ELEMENT_NODE) { 101 // Check for insurance popup containers 102 var popupElements = $(node).find('.insurance-popup, [data-insurance-popup], .popup-insurance').addBack('.insurance-popup, [data-insurance-popup], .popup-insurance'); 103 104 if (popupElements.length > 0) { 105 popupElements.each(function() { 106 var $popup = $(this); 107 108 // Only track if this popup has auto-display class (indicating it was auto-triggered) 109 // Don't interfere with manual tracking 110 if ($popup.hasClass('auto-display')) { 111 var triggerType = $popup.data('trigger-type') || 'auto'; 112 var popupType = $popup.data('popup-type') || 'regular'; 113 114 console.log('MutationObserver: Auto popup detected', {triggerType, popupType}); 115 116 // Track auto-fire impression only for auto-displayed popups 117 self.trackEvent('impression', { 118 trigger_type: triggerType, 119 popup_type: popupType 120 }); 121 } 122 }); 123 } 124 } 125 }); 126 } 127 }); 128 }); 129 130 // Start observing 131 observer.observe(document.body, { 132 childList: true, 133 subtree: true 134 }); 135 } 136 }, 137 138 // Core tracking function 139 trackEvent: function(eventType, data) { 140 if (!this.trackingEnabled) { 141 return; 142 } 143 144 data = data || {}; 145 146 // Debug: Log what data we received 147 console.log('External Tracker Debug:', { 148 eventType: eventType, 149 receivedData: data, 150 triggerTypeFromData: data.trigger_type, 151 willUseTriggerType: data.trigger_type || 'manual' 152 }); 153 154 var trackingData = { 155 action: 'handle_insurance_popup_event_v2', 156 session_id: this.sessionId, 157 event_type: eventType, 158 popup_type: data.popup_type || 'regular', 159 trigger_type: data.trigger_type || 'manual', 160 popup_version: data.popup_version || 'v2', 161 page_url: this.currentPageUrl, 162 page_id: this.currentPageId, 163 device_type: this.getDeviceType(), 164 user_id: data.user_id || this.getCurrentUserId(), 165 state: data.state || null, 166 insurance: data.insurance || null, 167 purchase_conversion: data.purchase_conversion || 0, 168 timestamp: new Date().toISOString() 169 }; 170 171 // Add any additional data 172 if (data.additional_data) { 173 trackingData.additional_data = JSON.stringify(data.additional_data); 174 } 175 176 // Use Beacon API for critical events (submissions) to guarantee delivery 177 var isCriticalEvent = ['insurance_submission', 'no_insurance_submission'].includes(eventType); 178 179 if (isCriticalEvent && navigator.sendBeacon) { 180 // Use Beacon API for guaranteed delivery during page transitions 181 // Convert to URL-encoded string instead of FormData for better WordPress compatibility 182 var params = new URLSearchParams();
183 Object.keys(trackingData).forEach(function(key) { 184 params.append(key, trackingData[key]); 185 }); 186 187 // Set proper Content-Type header for WordPress admin-ajax.php 188 var blob = new Blob([params.toString()], { 189 type: 'application/x-www-form-urlencoded' 190 }); 191 192 var success = navigator.sendBeacon(this.baseUrl, blob); 193 if (success) { 194 console.log('Insurance popup event tracked via Beacon (guaranteed delivery):', eventType); 195 } else { 196 console.warn('Beacon failed, falling back to AJAX:', eventType); 197 this.sendViaAjax(trackingData, eventType); // Fallback 198 } 199 } else { 200 // Use regular AJAX for non-critical events 201 this.sendViaAjax(trackingData, eventType); 202 } 203 }, 204 205 // Separate AJAX method for fallback and non-critical events 206 sendViaAjax: function(trackingData, eventType) { 207 $.ajax({ 208 url: this.baseUrl, 209 type: 'POST', 210 data: trackingData, 211 dataType: 'json', 212 timeout: 5000, 213 success: function(response) { 214 if (response.success) { 215 console.log('Insurance popup event tracked via AJAX:', eventType); 216 } else { 217 console.warn('Insurance popup tracking failed:', response.data); 218 } 219 }, 220 error: function(xhr, status, error) { 221 console.warn('Insurance popup tracking error:', error); 222 } 223 }); 224 }, 225 226 // Manual tracking functions for direct integration 227 trackImpression: function(triggerType, popupType) { 228 this.trackEvent('impression', { 229 trigger_type: triggerType || 'manual', 230 popup_type: popupType || 'regular' 231 }); 232 }, 233 234 trackPopupOpen: function(triggerType, popupType) { 235 this.trackEvent('popup_open', { 236 trigger_type: triggerType || 'manual', 237 popup_type: popupType || 'regular' 238 }); 239 }, 240 241 trackPopupClose: function(triggerType, popupType) { 242 this.trackEvent('close', { 243 trigger_type: triggerType || 'manual', 244 popup_type: popupType || 'regular' 245 }); 246 }, 247 248 trackInsuranceToggle: function(triggerType, popupType) { 249 this.trackEvent('insurance_toggle', { 250 trigger_type: triggerType || 'manual', 251 popup_type: popupType || 'regular' 252 }); 253 }, 254 255 trackNoInsuranceToggle: function(triggerType, popupType) { 256 this.trackEvent('no_insurance_toggle', { 257 trigger_type: triggerType || 'manual', 258 popup_type: popupType || 'regular' 259 }); 260 }, 261 262 trackInsuranceSubmission: function(triggerType, popupType) { 263 this.trackEvent('insurance_submission', { 264 trigger_type: triggerType || 'manual', 265 popup_type: popupType || 'regular' 266 }); 267 }, 268 269 trackNoInsuranceSubmission: function(triggerType, popupType) { 270 this.trackEvent('no_insurance_submission', { 271 trigger_type: triggerType || 'manual', 272 popup_type: popupType || 'regular' 273 }); 274 }, 275 276 // Utility function to disable tracking 277 disable: function() { 278 this.trackingEnabled = false; 279 }, 280 281 // Utility function to enable tracking 282 enable: function() { 283 this.trackingEnabled = true; 284 }, 285 286 // Get device type from insurance_analytics or detect from user agent 287 getDeviceType: function() { 288 // First try to get from localized variables 289 if (typeof insurance_analytics !== 'undefined' && insurance_analytics.device_type) { 290 return insurance_analytics.device_type; 291 } 292 293 // Fallback to client-side detection 294 var userAgent = navigator.userAgent || navigator.vendor || window.opera; 295 296 // Check for mobile devices 297 if (/android/i.test(userAgent) || 298 /iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || 299 (window.screen && window.screen.width < 768)) { 300 return 'mobile'; 301 } 302 303 return 'desktop'; 304 }, 305 306 // Get current WordPress user ID if logged in 307 getCurrentUserId: function() { 308 // First try to get from localized variables 309 if (typeof insurance_analytics !== 'undefined' && insurance_analytics.user_id
309) { 310 return insurance_analytics.user_id; 311 } 312 313 // Try to get from global WordPress variables 314 if (typeof woocommerce_params !== 'undefined' && woocommerce_params.user_id) { 315 return woocommerce_params.user_id; 316 } 317 318 // Check for user ID in cookies (some themes set this) 319 var userIdCookie = this.getCookie('wp_user_id'); 320 if (userIdCookie) { 321 return parseInt(userIdCookie); 322 } 323 324 // Return null if no user is logged in 325 return null; 326 }, 327 328 // Cookie utility function for getCurrentUserId 329 getCookie: function(name) { 330 var nameEQ = name + "="; 331 var ca = document.cookie.split(';'); 332 for (var i = 0; i < ca.length; i++) { 333 var c = ca[i]; 334 while (c.charAt(0) === ' ') c = c.substring(1, c.length); 335 if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length); 336 } 337 return null; 338 }, 339 340 // Set cookie utility function 341 setCookie: function(name, value, days) { 342 var expires = ""; 343 if (days) { 344 var date = new Date(); 345 date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 346 expires = "; expires=" + date.toUTCString(); 347 } 348 document.cookie = name + "=" + value + expires + "; path=/; SameSite=Lax"; 349 } 350 }; 351 352 // Initialize when document is ready 353 $(document).ready(function() { 354 console.log('Insurance Popup Tracker: Document ready, checking for variables...'); 355 356 // Defensive check: Clear any old sbr_ajax that might interfere 357 try { 358 if (typeof sbr_ajax !== 'undefined') { 359 console.warn('Insurance Popup Tracker: Clearing old sbr_ajax variable'); 360 delete window.sbr_ajax; 361 } 362 } catch(e) { 363 // Ignore errors if sbr_ajax can't be deleted 364 } 365 366 // Check if required variables are available 367 if (typeof insurance_analytics === 'undefined') { 368 console.error('Insurance Popup Tracker: insurance_analytics variables not found. Check if script is properly enqueued.'); 369 console.log('Insurance Popup Tracker: Available variables:', Object.keys(window).filter(k => k.includes('insurance') || k.includes('analytics'))); 370 return; 371 } 372 373 console.log('Insurance Popup Tracker: Variables found, initializing tracker...'); 374 console.log('Insurance Popup Tracker: Using variables:', insurance_analytics); 375 376 // Initialize the tracker 377 window.InsurancePopupTracker.init(); 378 }); 379 380 // Expose manual tracking functions globally for easy integration 381 window.trackInsuranceImpression = function(triggerType, popupType) { 382 window.InsurancePopupTracker.trackImpression(triggerType, popupType); 383 }; 384 385 window.trackInsurancePopupOpen = function(triggerType, popupType) { 386 window.InsurancePopupTracker.trackPopupOpen(triggerType, popupType); 387 }; 388 389 window.trackInsurancePopupClose = function(triggerType, popupType) { 390 window.InsurancePopupTracker.trackPopupClose(triggerType, popupType); 391 }; 392 393 window.trackInsuranceToggle = function(triggerType, popupType) { 394 window.InsurancePopupTracker.trackInsuranceToggle(triggerType, popupType); 395 }; 396 397 window.trackNoInsuranceToggle = function(triggerType, popupType) { 398 window.InsurancePopupTracker.trackNoInsuranceToggle(triggerType, popupType); 399 }; 400 401 window.trackInsuranceSubmission = function(triggerType, popupType) { 402 window.InsurancePopupTracker.trackInsuranceSubmission(triggerType, popupType); 403 }; 404 405 window.trackNoInsuranceSubmission = function(triggerType, popupType) { 406 window.InsurancePopupTracker.trackNoInsuranceSubmission(triggerType, popupType); 407 }; 408 409})(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.