1/** 2 * HotelBox Cross-Domain Tracking. 3 * 4 * Uses localStorage and postMessage API to link visitor identities 5 * across different hotel websites under the same HotelBox account. 6 */ 7(function() { 8 'use strict'; 9 10 var config = window.hbCrossDomain || {}; 11 var linkedDomains = config.linkedDomains || []; 12 var currentDomain = config.currentDomain || window.location.hostname; 13 14 if (!linkedDomains.length) return; 15 16 var STORAGE_KEY = 'hb_cross_domain'; 17 18 // Store current fingerprint in localStorage for cross-domain retrieval. 19 function saveCrossDomainData() { 20 if (!window.hb_fp || !window.hb_sid) return; 21 22 var data = { 23 fingerprint: window.hb_fp, 24 session_id: window.hb_sid, 25 domain: currentDomain, 26 timestamp: Date.now() 27 }; 28 29 try { 30 localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); 31 } catch(e) {} 32 } 33 34 // Read cross-domain data from localStorage (set by another domain's iframe). 35 function readCrossDomainData() { 36 try { 37 var raw = localStorage.getItem(STORAGE_KEY); 38 if (!raw) return null; 39 40 var data = JSON.parse(raw); 41 // Only valid for 1 hour 42 if (Date.now() - data.timestamp > 3600000) { 43 localStorage.removeItem(STORAGE_KEY); 44 return null; 45 } 46 47 // Only use if from a different domain 48 if (data.domain === currentDomain) return null; 49 50 return data; 51 } catch(e) { 52 return null; 53 } 54 } 55 56 // Listen for postMessage from linked domains. 57 window.addEventListener('message', function(event) { 58 var origin = event.origin || ''; 59 var isLinked = linkedDomains.some(function(d) { 60 return origin.indexOf(d) !== -1; 61 }); 62 63 if (!isLinked) return; 64 65 var data = event.data; 66 if (!data || data.type !== 'hb_cross_domain') return; 67 68 // Store the cross-domain data 69 try { 70 localStorage.setItem(STORAGE_KEY, JSON.stringify({ 71 fingerprint: data.fingerprint, 72 session_id: data.session_id, 73 domain: data.domain, 74 timestamp: Date.now() 75 })); 76 } catch(e) {} 77 }); 78 79 // Append cross-domain data to outbound links to linked domains. 80 document.addEventListener('click', function(e) { 81 var link = e.target.closest('a[href]'); 82 if (!link) return; 83 84 var href = link.getAttribute('href') || ''; 85 86 var isLinkedDomain = linkedDomains.some(function(d) { 87 return href.indexOf(d) !== -1; 88 }); 89 90 if (!isLinkedDomain || !window.hb_fp) return; 91 92 // Append fingerprint as URL parameter for server-side matching 93 try { 94 var url = new URL(href, window.location.origin); 95 url.searchParams.set('hb_ref', window.hb_fp); 96 url.searchParams.set('hb_src', currentDomain); 97 link.setAttribute('href', url.toString()); 98 } catch(e) {} 99 }); 100 101 // Save on init 102 saveCrossDomainData(); 103 104 // Check for inbound cross-domain reference 105 var params = new URLSearchParams(window.location.search); 106 var inboundFp = params.get('hb_ref'); 107 var inboundSrc = params.get('hb_src'); 108 109 if (inboundFp && inboundSrc) { 110 try { 111 localStorage.setItem(STORAGE_KEY, JSON.stringify({ 112 fingerprint: inboundFp, 113 session_id: '', 114 domain: inboundSrc, 115 timestamp: Date.now() 116 })); 117 } catch(e) {} 118 } 119 120})();
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.