1/** 2 * UTM tracking condiviso (HubSpot + Forminator). 3 * 4 * Cattura i parametri UTM dalla URL, li conserva in un cookie e li propaga ai 5 * link interni; espone setHSFormValues() per i form HubSpot (chiamata in 6 * onFormReady) e popola automaticamente i campi nascosti dei form Forminator. 7 * 8 * La configurazione (dominio e nome del cookie) arriva da PHP via 9 * wp_localize_script -> window.namHubSpotUTM. Adattato da docs/utms-js.txt. 10 * 11 * @since 1.0.0 12 */ 13 14// jQuery Cookie plugin (bundled). 15!function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(jQuery)}(function(e){var n=/\+/g;function o(e){return t.raw?e:encodeURIComponent(e)}function i(e){return o(t.json?JSON.stringify(e):String(e))}function r(o,i){var r=t.raw?o:function(e){0===e.indexOf('"')&&(e=e.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return e=decodeURIComponent(e.replace(n," ")),t.json?JSON.parse(e):e}catch(e){}}(o);return e.isFunction(i)?i(r):r}var t=e.cookie=function(n,c,u){if(void 0!==c&&!e.isFunction(c)){if("number"==typeof(u=e.extend({},t.defaults,u)).expires){var a=u.expires,d=u.expires=new Date;d.setTime(+d+864e5*a)}return document.cookie=[o(n),"=",i(c),u.expires?"; expires="+u.expires.toUTCString():"",u.path?"; path="+u.path:"",u.domain?"; domain="+u.domain:"",u.secure?"; secure":""].join("")}for(var f,p=n?void 0:{},s=document.cookie?document.cookie.split("; "):[],m=0,v=s.length;m<v;m++){var x=s[m].split("="),k=(f=x.shift(),t.raw?f:decodeURIComponent(f)),l=x.join("=");if(n&&n===k){p=r(l,c);break}n||void 0===(l=r(l))||(p[k]=l)}return p};t.defaults={},e.removeCookie=function(n,o){return void 0!==e.cookie(n)&&(e.cookie(n,"",e.extend({},o,{expires:-1})),!e.cookie(n))}}); 16 17( function ( $ ) { 18 'use strict'; 19 20 var config = window.namHubSpotUTM || {}; 21 22 // Dominio per l'attributo del cookie (vuoto = host corrente, gestito da WP/browser). 23 var cookieDomain = config.cookieDomain || ''; 24 25 // Dominio considerato "interno" per i controlli sul referrer. 26 var referrerDomain = config.cookieDomain || window.location.hostname; 27 28 var cookieName = config.cookieName || 'nam_last_impact'; 29 30 // Mappa per i form HubSpot: nome campo nascosto (SFDC) -> chiave UTM. 31 var FIELD_MAP_HUBSPOT = { 32 'acquisition_source__c': 'utm_source', 33 'acquisition_medium__c': 'utm_medium', 34 'acquisition_campaign__c': 'utm_campaign', 35 'acquisition_content__c': 'utm_content', 36 'acquisition_term__c': 'utm_term', 37 'last_acquisition_campaign_id': 'utm_id', 38 'acquisition_referral': 'ac_referral' 39 }; 40 41 // Mappa per i form Forminator: name del campo nascosto (id Forminator) -> chiave UTM. 42 // I name corrispondono agli id Forminator (hidden-N). 43 // hidden-1 "Lead Source" e hidden-6 "Last Acquisition Form" sono volutamente 44 // esclusi: hanno valore statico impostato direttamente nel campo Forminator. 45 // hidden-7 è già in uso per altro scopo nel Purchase form. 46 var FIELD_MAP_FORMINATOR = { 47 'hidden-2': 'utm_source', // Last Acquisition Source 48 'hidden-3': 'utm_medium', // Last Acquisition Medium 49 'hidden-4': 'utm_campaign', // Last Acquisition Campaign 50 'hidden-5': 'utm_term', // Last Acquisition Term 51 'hidden-8': 'utm_id' // Last Acquisition Campaign ID 52 }; 53 54 // --- Lettura parametri URL -------------------------------------------- 55 56 function getQueryParam( paramName ) { 57 var query = window.location.search; 58 var pos = query.indexOf( paramName + '=' ); 59 if ( pos === -1 ) { 60 return null; 61 } 62 var start = pos + paramName.length + 1; 63 var end = query.indexOf( '&', start ); 64 end = end > -1 ? end : query.length; 65 return query.substring( start, end ); 66 } 67 68 function getUTMvalues() { 69 var utmParams = [ 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'utm_id' ]; 70 var utmValues = utmParams.reduce( function ( values, param ) { 71 var raw = getQueryParam( param ); 72 values[ param ] = raw ? raw.toLowerCase() : 'not-provided'; 73 return values; 74 }, {} ); 75 76 var urlReferrer = document.referrer; 77 if ( urlReferrer && urlReferrer.indexOf( referrerDomain ) === -1 ) { 78 utmValues.ac_referral = urlReferrer; 79 if ( utmValues.utm_medium !== 'cpc' ) { 80 updateUtmForOrganic( utmValues, urlReferrer ); 81 } 82 } else { 83 utmValues.ac_referral = 'not-provided'; 84 } 85 86 if ( utmValues.utm_source === 'not-provided' && utmValues.utm_medium === 'not-provided' ) { 87 utmValues.utm_source = 'direct'; 88 } 89 return utmValues; 90 } 91 92 function updateUtmForOrganic( utmValues, urlReferrer ) { 93 var organicSearchEngines = [ 94 { name: 'google', excludes: [ 'mail.google' ] }, 95 { name: 'bing' }, 96 { name: 'baidu' } 97 ]; 98 for ( var i = 0; i < organicSearchEngines.length; i++ ) { 99 var engine = organicSearchEngines[ i ]; 100 var matches = urlReferrer.indexOf( engine.name ) > -1; 101 var excluded = engine.excludes && engine.excludes.some( function ( ex ) { 102 return urlReferrer.indexOf( ex ) > -1; 103 } ); 104 if ( matches && ! excluded ) { 105 utmValues.utm_source = engine.name; 106 utmValues.utm_medium = 'organic'; 107 utmValues.utm_content = window.location.pathname; 108 break; 109 } 110 } 111 } 112 113 // --- Cookie ----------------------------------------------------------- 114 115 function setLastImpactCookie() { 116 var v = getUTMvalues(); 117 var cookieParams = { 118 utm_source: v.utm_source, 119 utm_medium: v.utm_medium, 120 utm_campaign: v.utm_campaign,
121 utm_content: v.utm_content, 122 utm_term: v.utm_term, 123 utm_id: v.utm_id, 124 ac_referral: v.ac_referral 125 }; 126 var options = { expires: 1 / 24, path: '/' }; 127 if ( cookieDomain ) { 128 options.domain = cookieDomain; 129 } 130 $.cookie( cookieName, JSON.stringify( cookieParams ), options ); 131 } 132 133 // --- Propagazione UTM ai link interni --------------------------------- 134 135 function attachUrlVarsToLinks() { 136 var currentUrl = new URL( window.location.href ); 137 var params = new URLSearchParams( currentUrl.search ); 138 139 var toDelete = []; 140 params.forEach( function ( value, key ) { 141 if ( key.indexOf( 'utm' ) === -1 ) { 142 toDelete.push( key ); 143 } 144 } ); 145 toDelete.forEach( function ( key ) { 146 params.delete( key ); 147 } ); 148 149 if ( params.toString() === '' ) { 150 return; 151 } 152 153 document.querySelectorAll( 'a' ).forEach( function ( link ) { 154 try { 155 var linkUrl = new URL( link.href ); 156 if ( linkUrl.hostname === currentUrl.hostname ) { 157 var linkParams = new URLSearchParams( linkUrl.search ); 158 params.forEach( function ( value, key ) { 159 linkParams.set( key, value ); 160 } ); 161 linkUrl.search = linkParams.toString(); 162 link.href = linkUrl.toString(); 163 } 164 } catch ( e ) {} 165 } ); 166 } 167
168 // --- Popolamento campi nascosti --------------------------------------- 169 170 function setInputValues( values ) { 171 Object.keys( values ).forEach( function ( key ) { 172 if ( values[ key ] !== null && values[ key ] !== undefined ) { 173 $( 'input[name="' + key + '"]' ).val( values[ key ] ).change(); 174 } 175 } ); 176 } 177 178 /** 179 * Restituisce i valori UTM correnti: dai parametri URL se presenti, 180 * altrimenti dal cookie (creandolo se manca). 181 */ 182 function getSourceValues() { 183 if ( ! $.cookie( cookieName ) ) { 184 setLastImpactCookie(); 185 } 186 return getQueryParam( 'utm_source' ) 187 ? getUTMvalues() 188 : JSON.parse( $.cookie( cookieName ) ); 189 } 190 191 /** 192 * Popola i campi nascosti in pagina secondo la mappa passata 193 * (nome campo -> chiave UTM). Riusabile per HubSpot e Forminator. 194 * 195 * @param {Object} map 196 */ 197 function applyFieldMap( map ) { 198 var source = getSourceValues(); 199 var values = {}; 200 Object.keys( map ).forEach( function ( fieldName ) { 201 values[ fieldName ] = source[ map[ fieldName ] ]; 202 } ); 203 setInputValues( values ); 204 } 205 206 // Esposta per il callback onFormReady dei form HubSpot. 207 window.setHSFormValues = function () { 208 applyFieldMap( FIELD_MAP_HUBSPOT ); 209 return true; 210 }; 211 212 // --- Bootstrap -------------------------------------------------------- 213 214 $( function () { 215 // Su ogni sessione: crea il cookie se l'utente ha UTM ma il cookie manca, 216 // o se arriva da un referrer esterno al dominio. 217 var hasUtm = getQueryParam( 'utm_source' ); 218 var externalReferrer = document.referrer !== '' && document.referrer.indexOf( referrerDomain ) === -1; 219 if ( ( ! $.cookie( cookieName ) && hasUtm ) || externalReferrer ) { 220 setLastImpactCookie(); 221 } 222
223 // Propaga gli UTM ai link interni (utile quando i cookie non sono accettati). 224 if ( window.location.href.indexOf( '?' ) > -1 && window.location.href.indexOf( 'page' ) === -1 ) { 225 attachUrlVarsToLinks(); 226 } 227 228 // Forminator: popola i campi nascosti dei form già renderizzati a DOM ready 229 // e di quelli ricaricati via ajax (paginazione/step). 230 if ( document.querySelector( '.forminator-custom-form' ) ) { 231 applyFieldMap( FIELD_MAP_FORMINATOR ); 232 } 233 $( document ).on( 'after:forminator:form:render', function () { 234 applyFieldMap( FIELD_MAP_FORMINATOR ); 235 } ); 236 } ); 237 238} )( 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.