1// (function(history){ 2// var replaceState = history.replaceState; 3// history.replaceState = function(state) { 4// if (typeof history.onreplacestate == "function") { 5// history.onreplacestate({state: state}); 6// } 7// return replaceState.apply(history, arguments); 8// }; 9// })(window.history); 10// 11// window.onpopstate = history.onreplacestate = function(e) { 12// var domain = getDomainName() 13// console.log(e.state.path) 14// Cookies.set('handl_url', e.state.path, { 15// expires: parseInt(handl_utm_cookie_duration[0]), 16// domain: domain, 17// sameSite:'None', 18// secure: true } 19// ); 20// } 21 22var qvars = getUrlVars() 23var domain = getDomainName() 24 25jQuery(function($) { 26 if (handl_utm_cookie_duration[1] === '1' && 27 typeof(TVE) === "undefined" //thrive editor fix 28 ){ 29 console.log('Running HandL'); 30 RunHandL() 31 32 const borlabsCookie = Cookies.get('borlabs-cookie'); // Get the cookie as a JSON string 33 if (borlabsCookie) { 34 try { 35 // Parse the JSON string into an object 36 const cookieData = JSON.parse(borlabsCookie); 37 38 // Check if the 'marketing' key has 'handl-utm-grabber' 39 if (cookieData.consents.marketing.includes('handl-utm-grabber')) { 40 console.log("handl-utm-grabber checked by Borlabs.. RunHandL..."); 41 RunHandL() 42 } else { 43 console.log("handl-utm-grabber not checked by Borlabs"); // or return false; 44 } 45 } catch (e) { 46 console.error('Error parsing JSON:', e); 47 } 48 } 49 } 50}); 51 52 53function RunHandL(){ 54 window.utms_js = {} 55 window.gaNames = [] 56 57 //simulate referrer locally 58 // Object.defineProperty(document, "referrer", {get : function(){ return "https://google.com"; }}); 59 60 SetRefLink('handlID', Math.floor(Math.random() * Date.now()), false, 0) 61 62 GAClientID() 63 setHandLParams() 64 65 // console.log("after handl params") 66 67 RunFieldFiller() 68 // Occasionally, the page takes longer to render, so it makes sense to introduce a delay. However, we have not yet investigated the potential negative effects of doing this when it is not necessary. 69 // setTimeout(RunFieldFiller, 1000) 70 71 jQuery.each(handl_utm_predefined, function( i,v ) { 72 let cookie_name = v.name; 73 let value = v.value 74 75 if ( value.startsWith('[') && value.endsWith(']') ){ //it's a shortcode! 76 value = v.value.replace(/^\[|\]$/g,''); 77 }else{ //it is a hardcoded default value 78 value = cookie_name 79 } 80 81 if ( ['_ga','gaclientid'].indexOf(value) > -1 ){ 82 gaNames.push(cookie_name) 83 } 84 85 if (cookie_name != ''){ 86 var cookie_field = GetQVars(value,qvars) 87 88 if (cookie_field == ''){ 89 cookie_field = Cookies.get(value) 90 } 91 92 if ( cookie_field != '' && cookie_field != 'PANTHEON_STRIPPED' ){ 93 utms_js[cookie_name] = cookie_field 94 SetRefLink(cookie_name, cookie_field, true, 0) 95 } 96 } 97 }) 98 99 populateLinks() 100 101 jQuery(document).on( 'nfFormReady', function() { 102 // Loop through each form in nfForms array 103 nfForms.forEach(form => { 104 form.fields.map(item => { 105 if (item.default) { 106 var matches = String(item.default).match(/^{(\w+):(\w+)/) 107 if (matches && matches.length == 3) { 108 let key = matches[1] 109 let value = matches[2] 110 111 if (key === 'handl') { 112 console.log(key, value) 113 jQuery('#nf-field-' + item.id).val(Cookies.get(value)) 114 } 115 } 116 } 117 }) 118 }) 119 120 //hide hidden fields 121 // jQuery('.nf-field-container.hidden-container').map( (i, item) => jQuery(item).parents().eq(4).hide()) 122 }) 123 124 document.dispatchEvent(new Event('HandL-After-Main-Function')); 125} 126 127function RunFieldFiller(){ 128
129 let cookieOptions = { 130 domain: domain, 131 secure: true, 132 sameSite: 'None' 133 }; 134 135 if (!parseInt(handl_utm_session_cookies?.enabled)) { 136 cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]); 137 } 138 139 Cookies.set('user_agent', navigator.userAgent, cookieOptions) 140 141 jQuery.each(handl_utm_all_params, function( i,vi ) { 142 var cookie_field = GetQVars(vi,qvars) 143 144 var cookie_params = [vi] 145 if ( handl_utm_first_touch_params.includes(vi) ) 146 cookie_params.push('first_'+vi) 147 148 cookie_params.forEach( (v, ind) => { 149 150 if ( cookie_field != '' && cookie_field != 'PANTHEON_STRIPPED' ){ 151 if ( v.startsWith('first_') && Cookies.get(v) != undefined ){ 152 //do not update the first attributes... 153 }else{ 154 if (cookie_field.includes('#')) { 155 cookie_field = cookie_field.split('#')[0]; 156 } 157 158 let cookieOptions = { 159 domain: domain, 160 sameSite: 'None', 161 secure: true 162 }; 163 164 if (!parseInt(handl_utm_session_cookies?.enabled)) { 165 cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]); 166 } 167 168 Cookies.set(v, cookie_field, cookieOptions); 169 } 170 } 171 172 var curval = decodeURI(Cookies.get(v)) 173 curval = curval != 'undefined' ? curval : '' 174 if (curval != 'undefined') { 175 curval = sanitizeInput(curval); 176 utms_js[v] = curval 177 curval = decodeURIComponent(curval) 178 // curval = curval.replace(/[%]/g,' ') 179 if (v == 'username') { 180 //Maybe this should apply to all... We'll see... 181 curval = curval.replace(/\+/g, ' ') 182 } 183 184 jQuery('input[name=\"'+v+'\"]').val(curval) 185 jQuery('input#'+v).val(curval) 186 jQuery('input.'+v).val(curval) 187 jQuery('input#form-field-'+v).val(curval) 188 189 //for nested input fix 190 jQuery('#'+v).find('input').val(curval) 191 jQuery('.'+v).find('input').val(curval) 192 193 jQuery("[data-original_id='"+v+"']").val(curval) 194 jQuery("[data-name='"+v+"']").val(curval) 195 jQuery("[data-name='"+v.replace(/_/g,'')+"']").val(curval) //Active Campaign 196 jQuery("[placeholder='"+v+"']").val(curval) //Dyanmics 365 + Generic 197 198 199 200 if (v.length > 4){ // this is for making sure wildcards are not hyper sensitive. 201 //wildcard selector 202 jQuery("[name*="+v+"]").val(curval) 203 jQuery("[id*="+v+"]").val(curval) 204 jQuery("[class*="+v+"]").val(curval) 205 206 jQuery("[class*="+v+"_out]").html(curval) 207 jQuery("[id*="+v+"_out]").html(curval) 208 } 209 210 } 211 }) 212 }); 213} 214 215function handlUtmIsInsideAdminBar($el) { 216 return $el.closest('#wpadminbar').length > 0; 217} 218 219function populateLinks(){ 220 jQuery('.utm-out-js, .utm-out-js a').each(function(){ 221 var $el = jQuery(this); 222 if (handlUtmIsInsideAdminBar($el)) { 223 return; 224 } 225 var merged_raw = jQuery.extend( {}, utms_js ) 226 var merged = Object.keys(merged_raw) 227 .filter(key => handl_utm_append_params.includes(key)) 228 .reduce((obj, key) => { 229 if (merged_raw[key]) { 230 obj[key] = decodeURIComponent(merged_raw[key]); 231 } 232 return obj; 233 }, {}); 234 merged = jQuery.extend(merged, getSearchParams(this.href)) 235 var current_page = window.location.href.split('?')[0] 236 if ( 237 this.href !== undefined && 238 this.href !== "" && 239 !this.href.match("#") && 240 !this.href.startsWith("tel:") && 241 !this.href.startsWith("mailto:") && 242 !this.href.startsWith("sms:") && 243 !jQuery(this).attr('onclick') && 244 !jQuery(this).closest('.no-utm').length // Check if the link or any of its parents have the no-utm class 245 // this.href.match(new RegExp("^"+current_page+"$")) == null 246 ){ 247 var href = this.href.split("?")[0]; 248 if ( !jQuery.isEmptyObject(merged) ) 249 this.href = href+"?"+decodeURIComponent(jQuery.param(merged)) 250 } 251 }) ; 252 253 // console.log(handl_utm) 254 // console.log(utms_js) 255 256 jQuery('.utm-out, .utm-out a').each(function(){ 257 var $el = jQuery(this); 258 if (handlUtmIsInsideAdminBar($el)) { 259 return; 260 } 261 var merged_raw = jQuery.extend( {}, handl_utm, utms_js ) 262 var merged = Object.keys(merged_raw) 263 .filter(key => handl_utm_append_params.includes(key)) 264 .reduce((obj, key) => { 265 if (merged_raw[key]) { 266 obj[key] = decodeURIComponent(merged_raw[key]); 267 } 268 return obj 269 }, {}); 270 merged = jQuery.extend(merged, getSearchParams(this.href)) 271 var current_page = window.location.href.split('?')[0] 272 if ( 273 this.href !== undefined && 274 this.href !== "" && 275 !this.href.match("#") && 276 !this.href.startsWith("tel:") && 277 !this.href.startsWith("mailto:") && 278 !this.href.startsWith("sms:") && 279 !jQuery(this).closest('.no-utm').length // Check if the link or any of its parents have the no-utm class 280 // !jQuery(this).attr('onclick') && 281 // this.href.match(new RegExp("^"+current_page+"$")) == null 282 ){ 283 var href = this.href.split("?")[0]; 284 var parts = [] 285 if (this.href.match("#")){ 286 parts = this.href.split("#") 287 if (parts[1] != ""){ 288 href = parts[0] 289 } 290 } 291 292 // console.log(parts, href) 293 if ( !jQuery.isEmptyObject(merged) ){ 294 if (this.href.match("#") && parts.length == 2){ 295 this.href = href+"?"+decodeURIComponent(jQuery.param(merged))+"#"+parts[1].split("?")[0] 296 }else{ 297 this.href = href+"?"+decodeURIComponent(jQuery.param(merged)) 298 } 299 } 300 } 301 }); 302
303 jQuery('.utm-src').each(function(){ 304 if (handlUtmIsInsideAdminBar(jQuery(this))) { 305 return; 306 } 307 var target_url 308 if (this.src){ 309 target_url = this.src 310 }else if (jQuery(this).data('url')){ 311 target_url = jQuery(this).data('url') 312 }else if (jQuery(this).data('src')){ 313 target_url = jQuery(this).data('src') 314 } 315 316 var merged_raw = jQuery.extend( {}, handl_utm, utms_js ) 317 var merged = Object.keys(merged_raw) 318 .filter(key => handl_utm_append_params.includes(key)) 319 .reduce((obj, key) => { 320 if (merged_raw[key]) { 321 obj[key] = decodeURIComponent(merged_raw[key]); 322 } 323 return obj; 324 }, {}); 325 merged = jQuery.extend( merged, getSearchParams(target_url) ) 326 327 var src = target_url.split("?")[0]; 328 if ( !jQuery.isEmptyObject(merged) ){ 329 var final_target = src + "?" + decodeURIComponent(jQuery.param(merged)) 330 if (this.src) { 331 this.src = final_target 332 }else if (jQuery(this).data('url')){ 333 jQuery(this).data('url', final_target) 334 } 335 } 336 }); 337 338 jQuery("[data-fillout-id]").each(function(){ 339 handl_utm_append_params.map(t=>{ 340 jQuery(this).attr(`data-${t}`, utms_js[t]) 341 }) 342 343 var script = document.createElement('script'); 344 script.src ='https://server.fillout.com/embed/v1/'; 345 document.head.appendChild(script); 346 347 }) 348} 349 350function getSearchParams(url,k){ 351 var p={}; 352 var a = document.createElement('a'); 353 a.href = url; 354 a.search.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(s,k,v){p[k]=v}) 355 return k?p[k]:p; 356} 357 358function GetQVars(v,qvars){ 359 if (qvars[v] != undefined) { 360 return qvars[v] 361 } 362 return '' 363} 364 365function getUrlVars() { 366 var vars = {}; 367 window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { 368 vars[key] = decodeURIComponent(value); 369 }); 370 return vars; 371} 372 373function GAClientID(){ 374 if ( typeof(ga) == 'function' && typeof(ga.getAll) == 'function'){ 375 var trackers = ga.getAll(); 376 if (trackers.length > 0 ){ 377 //maybe we'll update this later, so we can loop all the tracking ids... 378 var entries = Object.entries({"clientId":"gaclientid","referrer":"organic_source"}) 379 var domain = getDomainName() 380 for (const [gaName, handlName] of entries) { 381 var gaValue = trackers[0].get(gaName) 382 if (gaValue !== undefined) { 383 if (gaName != 'clientId'){ // we should reset the array for anythng other than clientId 384 gaNames = [] 385 } 386 387 gaNames.push(handlName) 388 389 for (const curName of gaNames){ 390 // console.log(curName, gaValue) 391 utms_js[curName] = gaValue 392 let cookieOptions = { 393 domain: domain, 394 sameSite: 'None', 395 secure: true 396 }; 397 398 if (!parseInt(handl_utm_session_cookies?.enabled)) { 399 cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]); 400 } 401 402 Cookies.set(curName, gaValue, cookieOptions); 403 // console.log(`Setting ${handlName} as ${gaValue}`) 404 jQuery('input[name=\"' + curName + '\"]').val(gaValue) 405 jQuery('input#' + curName).val(gaValue) 406 jQuery('input.' + curName).val(gaValue) 407 } 408 409 // so we can include gaclientid to the links incase needed 410 populateLinks() 411 } 412 } 413 } 414 }else{ 415 setTimeout(GAClientID,500); 416 } 417} 418 419function getDomainName(){ 420 var name="HandLtestDomainName" 421 var value="HandLtestDomainValue" 422 var host=location.host 423 var domain; 424 425 // Use the configured domain instead of probing with a test c
425ookie. 426 if (typeof handl_utm_cookie_domain !== 'undefined' && handl_utm_cookie_domain[0]) { 427 var configuredDomain = handl_utm_cookie_domain[0] 428 var configuredHost = configuredDomain.replace(/^\./, '').toLowerCase() 429 var currentHost = location.hostname.toLowerCase() 430 if (currentHost !== configuredHost && !currentHost.endsWith('.' + configuredHost)) { 431 console.warn('HandL UTM Grabber: the Domain setting "' + configuredDomain + '" does not match this site\'s host "' + location.hostname + '" â the browser may reject cookies set for that domain. Update it in HandL UTM Grabber â Options.') 432 } 433 return configuredDomain 434 } 435 436 if (host.split('.').length === 1){ 437 domain = ''; 438 }else{ 439 var domainParts = host.split('.'); 440 domainParts.shift(); 441 domain = '.'+domainParts.join('.'); 442 Cookies.set(name, value, { 443 domain: domain, 444 secure: true, 445 sameSite: 'None' 446 }) 447 if (Cookies.get(name) == null || Cookies.get(name) != value) 448 { 449 domain = '.'+host; 450 } 451 } 452 453 return domain; 454} 455 456function setHandLParams(){ 457 // console.log("set handl params") 458 459 SetRefLink('handl_url_base', document.location.origin + document.location.pathname, true, 0) 460 SetRefLink('handl_url', document.location.href, true, 0) 461 SetRefLink('handl_ref', document.referrer, true, 0) 462 SetRefLink('handl_ref_domain', document.referrer == '' ? '' : this.get_url_domain(document.referrer), true, 0) 463 SetRefLink('handl_landing_page', document.location.href, false, 0) 464 SetRefLink('handl_landing_page_base', new URL(document.location.href).origin + new URL(document.location.href).pathname, false, 0) 465 SetRefLink('handl_original_ref', document.referrer, false, 0) 466 467 let original_ref = Cookies.get('handl_ref_domain') 468 let this_domain = document.location.host 469 let source = "Other"; 470 if (original_ref == '') { 471 source = "Direct"; 472 }else if ( original_ref.match(/google\.co.*/i) !== null ){ 473 source = "Google"; 474 }else if ( original_ref.match(/bing\.co.*/i) !== null ){ 475 source = "Bing"; 476 }else if ( original_ref.match(/instagram\.co.*/i) !== null ){ 477 source = "Instagram"; 478 }else if ( original_ref.match(/facebook\.co.*/i) !== null || original_ref.match(/fb\.co.*/i) !== null ){ 479 source = "Facebook"; 480 }else if ( original_ref.match(/reddit\.com/i) !== null ){ 481 source = "Reddit"; 482 }else if ( original_ref.match(/twitter\.com/i) !== null || original_ref.match(/t\.co$/i) !== null || original_ref.match(/x\.com$/i) !== null ){ 483 source = "Twitter"; 484 }else if ( original_ref.match(/snapchat\.co.*/i) !== null ){ 485 source = "Snapchat"; 486 }else if ( original_ref.match(/youtube\.co.*/i) !== null ){ 487 source = "YouTube"; 488 }else if ( original_ref.match(/pinterest\.co.*/i) !== null ){ 489 source = "Pinterest"; 490 }else if ( original_ref.match(/linkedin\.co.*/i) !== null ){ 491 source = "LinkedIn"; 492 }else if ( original_ref.match(/tumblr\.com/i) !== null ){ 493 source = "Tumblr"; 494 }else if ( original_ref.match(/duckduckgo\.co.*/i) !== null ){ 495 source = "Duckduckgo"; 496 }else if ( original_ref.match(/openai\.com/i) !== null || original_ref.match(/chatgpt\.com/i) !== null ){ 497 source = "OpenAI"; 498 }else if ( original_ref.match(/perplexity\.ai/i) !== null ){ 499 source = "Perplexity"; 500 }else if ( original_ref.match(/claude\.ai/i) !== null ){ 501 source = "Claude"; 502 }else if ( original_ref.match(/gemini\.google\.com/i) !== null ){ 503 source = "Gemini"; 504 }else if ( original_ref.match(/copilot\.microsoft\.com/i) !== null ){ 505 source = "Copilot"; 506 }else if ( original_ref.match(/yelp\.com/i) !== null ){ 507 source = "Yelp"; 508 }else if (this_domain == original_ref){ 509 source = "Internal"; 510 } 511 512 if( 513 ( !Cookies.get('organic_source_str') || Cookies.get('organic_source_str') == '' ) || 514 ( Cookies.get('organic_source_str') && Cookies.get('organic_source_str') != '' && ['Internal','Direct'].indexOf(source) == -1 ) 515 ){ 516 SetRefLink('organic_source', document.referrer, true, 0) 517 SetRefLink('organic_source_str', source, true, 0) 518 } 519 520 var qvars = getUrlVars() 521 var googlePaidFromQuery = 522 Object.keys(qvars).indexOf('gad_source') !== -1 || 523 Object.keys(qvars).indexOf('gad_campaignid') !== -1 || 524 Object.keys(qvars).indexOf('gclid') !== -1 || 525 Object.keys(qvars).indexOf('wbraid') !== -1 || 526 Object.keys(qvars).indexOf('gbraid') !== -1 527 var googlePaidFromCookie = 528 Cookies.get('gclid') !== undefined || 529 Cookies.get('wbraid') !== undefined || 530 Cookies.get('gbraid') !== undefined 531 if (googlePaidFromQuery || googlePaidFromCookie) { 532 SetRefLink('organic_source_str', 'Google', true, 0) 533 } 534 535 let traffic_source = 'Other' 536 if ( 537 Cookies.get('gclid') != undefined || 538 Cookies.get('msclkid') != undefined || 539 Cookies.get('wbraid') != undefined || 540 Cookies.get('gbraid') != undefined || 541 Object.keys(qvars).indexOf('gclid') != -1 || 542 Object.keys(qvars).indexOf('msclkid') != -1 || 543 Object.keys(qvars).indexOf('wbraid') != -1 || 544 Object.keys(qvars).indexOf('gbraid') != -1 || 545 (Cookies.get('fbclid') != undefined && Cookies.get('_fbc') != undefined) || 546 (Object.keys(qvars).indexOf('fbclid') != -1 && Cookies.get('_fbc') != undefined) || 547 Object.keys(qvars).indexOf('gad_source') != -1 || 548 Object.keys(qvars).indexOf('gad_campaignid') != -1 549 ){ 550 traffic_source = 'Paid' 551 }
551else if ( ['Google','Bing','Yahoo','Duckduckgo'].indexOf(Cookies.get('organic_source_str')) > -1 ){ 552 traffic_source = 'Organic' 553 }else if ( ['Facebook','Twitter','Instagram','Snapchat','YouTube','Pinterest','LinkedIn','Tumblr','Reddit'].indexOf(Cookies.get('organic_source_str')) > -1 ){ 554 traffic_source = 'Social' 555 }else if ( ['Internal','Direct'].indexOf(Cookies.get('organic_source_str')) > -1 ){ 556 traffic_source = 'Direct' 557 }else if ( Cookies.get('organic_source_str') && ['Internal'].indexOf(Cookies.get('organic_source_str')) == -1 ){ 558 traffic_source = 'Referral' 559 } 560 561 SetRefLink('traffic_source', traffic_source, true, 0) 562 SetRefLink('first_traffic_source', traffic_source, false, 0) 563 564 document.dispatchEvent(new CustomEvent('handl_cookies_set')); 565 566} 567 568function SetRefLink(field, value, overwrite, count){ 569 // console.log(`Trying ${count} for ${field} ---> ${value}`) 570 var domain = getDomainName() 571 572 if (Cookies.get(field) != value) { 573 if (Cookies.get(field) !== undefined && Cookies.get(field) != "" && !overwrite ){ 574 //bail... 575 // console.log(`No need to update... ${field}`) 576 }else if (Cookies.get(field) === undefined || Cookies.get(field) == '' || overwrite) { 577 if (count == undefined) { 578 count = 0 579 } 580 581 // utms_js[field] = value //not sure if we really need it here 582 // console.log(`Setting cookies for ${field} as ${value}`) 583 let cookieOptions = { 584 domain: domain, 585 sameSite: 'None', 586 secure: true 587 }; 588 589 if (!parseInt(handl_utm_session_cookies?.enabled)) { 590 cookieOptions.expires = parseInt(handl_utm_cookie_duration[0]); 591 } 592 593 Cookies.set(field, value, cookieOptions); 594 595 } else { 596 count = count + 1 597 if (count < 3) { 598 setTimeout(function () { 599 SetRefLink(field, value, overwrite, count) 600 }, 500) 601 } 602 } 603 } 604} 605 606function get_url_domain(url) { 607 let a = document.createElement('a'); 608 a.href = url; 609 return a.hostname; 610} 611 612//This is for OptinMonster events: https://optinmonster.com/docs/optinmonster-javascript-events-api/ 613document.addEventListener('om.Campaign.afterShow',function(){ 614 RunFieldFiller() 615}) 616 617window.addEventListener('CookiebotOnAccept', function (e) { 618 if (Cookiebot.consent.marketing) 619 { 620 RunHandL() 621 } 622}, false); 623 624document.addEventListener("cmplz_enable_category", function(consentData) { 625 var category = consentData.detail.category; 626 if (category==='marketing'){ 627 RunHandL() 628 } 629}); 630 631// Marketing consent granted -> capture; withdrawn -> clean up. No reload. 632function HandLOnMarketingConsentChange(changedConsentCategory) { 633 for (var key in changedConsentCategory) { 634 if (changedConsentCategory.hasOwnProperty(key)) { 635 if (key === 'marketing' && changedConsentCategory[key] === 'allow') { 636 console.log('Consent: Marketing consent granted, running HandL'); 637 RunHandL(); 638 } else if (key === 'marketing' && changedConsentCategory[key] === 'deny') { 639 console.log('Consent: Marketing consent withdrawn, removing HandL cookies'); 640 RemoveHandLCookies(); 641 } 642 } 643 } 644} 645 646// WP Consent API broadcasts (any consent manager, incl. our banner in manager mode). 647document.addEventListener('wp_listen_for_consent_change', function (e) { 648 HandLOnMarketingConsentChange(e.detail); 649}); 650 651// Our banner's own event, standalone mode. 652document.addEventListener('handl_consent_change', function (e) { 653 HandLOnMarketingConsentChange(e.detail); 654}); 655 656// Check if consent already exists on page load 657if (typeof wp_has_consent === 'function' && wp_has_consent('marketing')) { 658 console.log('WP Consent API: Marketing consent already granted'); 659} 660 661// ===== WPConsent (Cookies Banner & Privacy Suite) native integration ===== 662(function () { 663 function handlWPConsentRun(prefs) { 664 if (prefs && prefs.marketing) { 665 console.log('WPConsent: marketing consent granted, running HandL'); 666 RunHandL(); 667 } 668 } 669 // Fires on first save and on later updates (detail = preferences object). 670 window.addEventListener('wpconsent_consent_updated', function (e) { handlWPConsentRun(e.detail); }); 671 window.addEventListener('wpconsent_consent_saved', function (e) { handlWPConsentRun(e.detail); }); 672 // Already-consented visitors: WPConsent calls back immediately if state is known. 673 if (window.WPConsent && typeof WPConsent.registerListener === 'function') { 674 WPConsent.registerListener(handlWPConsentRun); 675 } 676})(); 677 678 679function afterBookingSelectDateAndTime(a){
680 Object.keys(a.bookings[0].customFields).forEach(function(key) { 681 let label = a.bookings[0].customFields[key].label 682 if (Cookies.get(label)){ 683 a.bookings[0].customFields[key].value = Cookies.get(label) 684 } 685 }); 686} 687 688window.ameliaActions = { 689 beforeBooking: function(x,y,a){ 690 afterBookingSelectDateAndTime(a) 691 x() 692 } 693} 694 695/* 696FormStack solution... 697 */ 698function FF_AutoFiller(v){ 699 let it = jQuery(v) 700 701 for ( vv of ['placeholder', 'title'] ) { 702 var ph = it.attr(vv) 703 var params = Object.values(handl_utm_all_params) 704 var n = params.findIndex( (p) => new RegExp(p,'i').test(ph) ) 705 if (n > -1){ 706 var cval = Cookies.get(params[n]) 707 it.val(cval).attr('value',cval) 708 } 709 } 710} 711setTimeout(function () { 712 jQuery('.fsCell.fsHidden>input').map( (i, v) => { FF_AutoFiller(v) }) 713}, 3000) 714 715jQuery(document).on('wsf-rendered', function(event, form_object, form_id, instance_id) { 716 RunFieldFiller() 717}); 718 719// function FF_OnAfterRender(){ 720// console.log("Form rendered successfully!"); 721// // var vars = ["Lead.UTM_Campaign__c","Lead.UTM_Medium__c","Lead.UTM_Source__c","Lead.UTM_Term__c","Lead.UTM_Content__c","Lead.GCLID__c","Lead.FBclid__c"] 722// // for (v of vars){ 723// // escape_v = v.replace(/\./g, '\\.') 724// // jQuery("#"+escape_v).val(Cookies.get(v)); 725// // } 726// return true; 727// } 728 729// wp.hooks.addFilter('jet.fb.inputs','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)}) 730// wp.hooks.addFilter('jet.fb.macro.field.value','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)}) 731// wp.hooks.addAction('jet.fb.observe.after','jet-plugins',function(x,y,z,t,i){console.log(x,y,z,t,i)}) 732 733//This is to support Jet Form Builder 734jQuery(document).on('jet-form-builder/after-init',function(e){ 735 RunFieldFiller() 736}) 737 738setTimeout(() => { //jotform iframe embed support 739 if (typeof(window.utms_js) == 'object' && typeof(iframeParams) == 'object'){ 740 var iframeParams = []; 741 iframeParams.push( jQuery.param(window.utms_js) ) 742 var src = ifr.src; 743 ifr.src = src + "?" + iframeParams.join('&'); 744 } 745}, "500"); 746 747 748jQuery( document ).on( 'elementor/popup/show' , function () { 749 setTimeout(RunFieldFiller, 1000) 750} ); 751 752//Borlabs cookie client-side 753window.addEventListener('borlabs-cookie-consent-saved', () => { 754 if (window.BorlabsCookie.Consents.hasConsent('handl-utm-grabber')){ 755 RunHandL() 756 } 757}); 758 759getAllHandLUTMParams = function() { 760 var values = {}; 761 762 Object.values(handl_utm_all_params).forEach(function(param) { 763 var value = Cookies.get(param); 764 if (value) { 765 values[param] = decodeURIComponent(value); 766 } 767 }); 768 769 return values; 770}; 771 772function getUserData() { 773 return { 774 fbc: Cookies.get('_fbc') || '', 775 fbp: Cookies.get('_fbp') || '', 776 client_ip_address: Cookies.get('handl_ip') || '', 777 client_user_agent: navigator.userAgent 778 }; 779} 780 781jQuery(document).ready(function($) { 782 setTimeout(() => { 783 var emailField = $('#email'); 784 var hasInitiatedCheckout = false; 785 786 // Check if we're on the WooCommerce checkout page 787 if ($('body').hasClass('woocommerce-checkout')) { 788 emailField.on('blur', function() { 789 if (!hasInitiatedCheckout && emailField.val().trim() !== '') { 790 hasInitiatedCheckout = true; 791 var userData = getUserData(); 792 userData.em = [emailField.val()]; 793 $.ajax({ 794 url: handl_ajax.ajax_url, 795 type: 'POST', 796 data: { 797 action: 'handl_initiate_checkout', 798 user_data: userData 799 }, 800 success: function(response) { 801 console.log('InitiateCheckout event sent:', response); 802 } 803 }); 804 } 805 }); 806 } 807 }, 500); 808}); 809 810function isFBCAPIEnabled() { 811 return handl_ajax.fb_capi_enabled === '1'; 812} 813 814jQuery(document).on('added_to_cart', function(event, fragments, cart_hash, button) { 815 if (!isFBCAPIEnabled()) return; 816 817 var productId = button.data('product_id'); 818 var quantity = button.data('quantity'); 819 820 if (typeof productId !== 'undefined' && typeof quantity !== 'undefined') { 821 var userData = getUserData(); 822 823 jQuery.ajax({ 824 url: handl_ajax.ajax_url, 825 type: 'POST', 826 data: { 827 action: 'handl_ajax_add_to_cart', 828 product_id: productId, 829 quantity: quantity, 830 user_data: userData 831 }, 832 success: function(response) { 833 console.log('AddToCart event sent:', response); 834 } 835 }); 836 } 837}); 838 839 840jQuery(function($) { 841 $('form.checkout').on('checkout_place_order', function() { 842 if (!isFBCAPIEnabled()) return; 843 844 var userData = getUserData(); 845 846 $.ajax({ 847 url: handl_ajax.ajax_url, 848 type: 'POST', 849 data: { 850 action: 'handl_add_payment_info', 851 user_data: userData 852 }, 853 success: function(response) { 854 console.log('AddPaymentInfo event sent:', response); 855 } 856 }); 857 }); 858}); 859 860function sanitizeInput(input) { 861 var element = document.createElement('div'); 862 element.innerText = input; 863 return element.innerHTML; 864} 865 866function getConsentStatus() { 867 if (!window.dataLayer) { 868 console.warn('dataLayer is not defined.'); 869 return null; 870 }
871 let consent = null; 872 // Iterate through dataLayer in reverse to find the latest consent event 873 for (let i = window.dataLayer.length - 1; i >= 0; i--) { 874 if (window.dataLayer[i][0] === 'consent' && window.dataLayer[i][1] === 'update') { 875 consent = window.dataLayer[i][2]; 876 break; 877 }else if (typeof window.dataLayer[i] === 'object' && window.dataLayer[i].value && window.dataLayer[i].value.event && window.dataLayer[i].value.event.includes('consent')) { 878 consent = window.dataLayer[i].value; 879 break; 880 } 881 } 882 return consent; 883} 884 885function isConsentDenied() { 886 const consentStatus = getConsentStatus(); 887 return consentStatus && (consentStatus.ad_user_data === 'denied' && (consentStatus.analytics_storage === 'denied' || !consentStatus.analytics_storage)); 888} 889 890function handleConsentStatus() { 891 if (isConsentDenied()) { 892 RemoveHandLCookies(); 893 } else { 894 RunHandL(); 895 } 896} 897 898function RemoveHandLCookies() { 899 console.log('Removing HandL cookies'); 900 Object.values(handl_utm_all_params).forEach(param => { 901 Cookies.remove(param, { path: '/', domain: getDomainName() }); 902 }); 903} 904 905(function() { 906 if (typeof handl_ajax.require_third_party_consent !== 'undefined' && handl_ajax.require_third_party_consent) { 907 if (!window.dataLayer) { 908 window.dataLayer = []; 909 } 910 911 const originalPush = window.dataLayer.push; 912 913 window.dataLayer.push = function(...args) { 914 args.forEach(entry => { 915 if ( 916 (Array.isArray(entry) && entry[0] === 'consent' && entry[1] === 'update') 917 || (entry.event && entry.event.includes('consent')) 918 || (entry.value && entry.value.event && entry.value.event.includes('consent')) 919 ) { 920 // Handle the consent update 921 // console.log(`entry3: ${JSON.stringify(entry)}`); 922 handleConsentStatus(); 923 } 924 925 // if (entry.event && entry.event.includes('marketing')) { 926 // // Handle the consent update 927 // console.log(`entry4: ${JSON.stringify(entry)}`); 928 // console.log(getConsentStatus()); 929 // } 930 // 931 // if (typeof entry === 'object' && Object.keys(entry).some(key => key.includes('marketing'))) { 932 // // Handle the consent update 933 // console.log(`entry5: ${JSON.stringify(entry)}`); 934 // console.log(getConsentStatus()); 935 // } 936 }); 937 938 return originalPush.apply(this, args); 939 }; 940 } 941 942 window.addEventListener("hs-form-event:on-ready", event => { 943 const form = window.HubSpotFormsV4.getFormFromEvent(event); 944 945 form.getFormFieldValues().then(fields => { 946 const fieldNames = new Set(fields.map(f => f.name)); 947 948 for (const field of handl_utm_all_params) { 949 const fieldName = `0-1/${field}`; 950 if (Cookies.get(field) && fieldNames.has(fieldName)) { 951 form.setFieldValue(fieldName, [Cookies.get(field)]); 952 } 953 } 954 }); 955 }); 956})();
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.