Last active
October 30, 2021 13:45
-
-
Save loldenburg/d83d7a5caf5c6640bebc3e5608de7a0f to your computer and use it in GitHub Desktop.
Tealium utagLoader Template which outputs Data Layer to console before Pre-Loader and as sent in utag.view/utag.link payload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//tealium universal tag - utag.loader ut4.48.##UTVERSION##, Copyright ##UTYEAR## Tealium.com Inc. All Rights Reserved. | |
// ATTENTION WHEN UPDATING THIS TEMPLATE!! | |
// CONTAINS CUSTOM CHANGES TO TEMPLATE (search for // CHANGE)!! | |
// CHANGE - Add TMSHelper Debugging Output | |
/** | |
* To start debug output to your console, open your browser console and run: | |
* TMSHelper.dbgActivate(); | |
* A cookie "teal_dbg" will be created. To stop debug output, delete that cookie | |
*/ | |
window.TMSHelper = window.TMSHelper || {}; | |
/** | |
* dbgActivate: activates debug mode by setting TMSHelper.dbgActive = 1 | |
* @module dbgActivate | |
*/ | |
TMSHelper.dbgActivate = function () { | |
/** | |
* TMSHelper.dbgActive: | |
* decides whether to log to the console (if 1=logging active). | |
* | |
* @type {int} | |
* @global | |
*/ | |
TMSHelper.dbgActive = 1; | |
document.cookie = "teal_dbg=1"; | |
console.log( | |
"set TMSHelper.dbgActive flag. Will enable console outputs of Pre-Loader State and all Data Layer Events (utag.view/.link). Delete the 'teal_dbg' cookie to stop." | |
); | |
}; | |
// set Debug Flag | |
if ( | |
location.search.search("teal_dbg=1") !== -1 || | |
document.cookie.indexOf("teal_dbg=1") !== -1 | |
) { | |
TMSHelper.dbgActivate(); | |
} | |
if (TMSHelper.dbgActive) { | |
console.log("--- utag_data (Pre-Loader Data Layer) before any Data processing, i.e. before running Pre-Loader Extensions. ---"); | |
console.log(JSON.stringify(utag_data, null, 4)); | |
} | |
// CHANGE END | |
##UTLOADEXTENSIONS## | |
if (typeof utag == "undefined" && !utag_condload) { | |
var utag = { | |
id:"##UTLOADERID##", | |
o:{}, | |
sender: {}, | |
send: {}, | |
rpt: { | |
ts: { | |
a: new Date() | |
} | |
}, | |
dbi: [], | |
db_log : [], | |
loader: { | |
q: [], | |
lc: 0, | |
f: {}, | |
p: 0, | |
ol: 0, | |
wq: [], | |
lq: [], | |
bq: {}, | |
bk: {}, | |
rf: 0, | |
ri: 0, | |
rp: 0, | |
rq: [], | |
ready_q : [], | |
sendq :{"pending":0}, | |
run_ready_q : function(){ | |
for(var i=0;i<utag.loader.ready_q.length;i++){ | |
utag.DB("READY_Q:"+i); | |
try{utag.loader.ready_q[i]()}catch(e){utag.DB(e)}; | |
} | |
}, | |
lh: function(a, b, c) { | |
a = "" + location.hostname; | |
b = a.split("."); | |
c = (/\.co\.|\.com\.|\.org\.|\.edu\.|\.net\.|\.asn\.|\...\.jp$/.test(a)) ? 3 : 2; | |
return b.splice(b.length - c, c).join("."); | |
}, | |
WQ: function(a, b, c, d, g) { | |
utag.DB('WQ:' + utag.loader.wq.length); | |
try { | |
// this picks up a utag_data items added after utag.js was loaded | |
// Gotcha: Data layer set after utag.js will not overwrite something already set via an extension. Only "new" values are copied from utag_data | |
// for case where utag_data is set after utag.js is loaded | |
if(utag.udoname && utag.udoname.indexOf(".")<0){ | |
utag.ut.merge(utag.data,window[utag.udoname],0); | |
} | |
// TBD: utag.handler.RE('view',utag.data,"bwq"); | |
// process load rules again if this flag is set | |
if(utag.cfg.load_rules_at_wait){ | |
utag.handler.LR(utag.data); | |
} | |
} catch (e) {utag.DB(e)}; | |
d=0; | |
g=[]; | |
for (a = 0; a < utag.loader.wq.length; a++) { | |
b = utag.loader.wq[a]; | |
b.load = utag.loader.cfg[b.id].load; | |
if (b.load == 4){ | |
//LOAD the bundled tag set to wait here | |
this.f[b.id]=0; | |
utag.loader.LOAD(b.id) | |
}else if (b.load > 0) { | |
g.push(b); | |
//utag.loader.AS(b); // moved: defer loading until flags cleared | |
d++; | |
}else{ | |
// clear flag for those set to wait that were not actually loaded | |
this.f[b.id]=1; | |
} | |
} | |
for (a = 0; a < g.length; a++) { | |
utag.loader.AS(g[a]); | |
} | |
if(d==0){ | |
utag.loader.END(); | |
} | |
}, | |
AS: function(a, b, c, d) { | |
utag.send[a.id] = a; | |
if (typeof a.src == 'undefined' || !utag.ut.hasOwn(a,'src')) { | |
a.src = utag.cfg.path + ((typeof a.name != 'undefined') ? a.name : 'ut' + 'ag.' + a.id + '.js') | |
} | |
a.src += (a.src.indexOf('?') > 0 ? '&' : '?') + 'utv=' + (a.v?utag.cfg.template+a.v:utag.cfg.v); | |
utag.rpt['l_' + a.id] = a.src; | |
b = document; | |
this.f[a.id]=0; | |
if (a.load == 2) { | |
utag.DB("Attach sync: "+a.src); | |
a.uid=a.id; | |
b.write('<script id="utag_' + a.id + '" src="' + a.src + '"></scr' + 'ipt>') | |
if(typeof a.cb!='undefined')a.cb(); | |
} else if(a.load==1 || a.load==3) { | |
if (b.createElement) { | |
c = 'utag_##UTLOADERID##_'+a.id; | |
if (!b.getElementById(c)) { | |
d = { | |
src:a.src, | |
id:c, | |
uid:a.id, | |
loc:a.loc | |
} | |
if(a.load == 3){d.type="iframe"}; | |
if(typeof a.cb!='undefined')d.cb=a.cb; | |
utag.ut.loader(d); | |
} | |
} | |
} | |
}, | |
GV: function(a, b, c) { | |
b = {}; | |
for (c in a) { | |
if (a.hasOwnProperty(c) && typeof a[c] != "function") b[c] = a[c]; | |
} | |
return b | |
}, | |
OU: function(tid, tcat, a, b, c, d, f, g) { | |
g = {}; | |
utag.loader.RDcp(g); | |
try { | |
if (typeof g['cp.OPTOUTMULTI'] != 'undefined') { | |
c = utag.loader.cfg; | |
a = utag.ut.decode(g['cp.OPTOUTMULTI']).split('|'); | |
for (d = 0; d < a.length; d++) { | |
b = a[d].split(':'); | |
if (b[1] * 1 !== 0) { | |
if (b[0].indexOf('c') == 0) { | |
for (f in utag.loader.GV(c)) { | |
if (c[f].tcat == b[0].substring(1)) c[f].load = 0; | |
// if we know the tid but don't know the category and this is a category opt out... | |
if (c[f].tid == tid && c[f].tcat == b[0].substring(1)) return true; | |
} | |
if (tcat == b[0].substring(1)) return true; | |
} else if (b[0] * 1 == 0) { | |
utag.cfg.nocookie = true | |
} else { | |
for (f in utag.loader.GV(c)) { | |
if (c[f].tid == b[0]) c[f].load = 0 | |
} | |
if (tid == b[0]) return true; | |
} | |
} | |
} | |
} | |
} catch (e) {utag.DB(e)} | |
return false; | |
}, | |
RDdom: function(o){ | |
var d = document || {}, l = location || {}; | |
o["dom.referrer"] = d.referrer; | |
o["dom.title"] = "" + d.title; | |
o["dom.domain"] = "" + l.hostname; | |
o["dom.query_string"] = ("" + l.search).substring(1); | |
o["dom.hash"] = ("" + l.hash).substring(1); | |
o["dom.url"] = "" + d.URL; | |
o["dom.pathname"] = "" + l.pathname; | |
o["dom.viewport_height"] = window.innerHeight || (d.documentElement?d.documentElement.clientHeight:960); | |
o["dom.viewport_width"] = window.innerWidth || (d.documentElement?d.documentElement.clientWidth:960); | |
}, | |
RDcp: function(o, b, c, d){ | |
b = utag.loader.RC(); | |
for (d in b) { | |
if (d.match(/utag_(.*)/)) { | |
for (c in utag.loader.GV(b[d])) { | |
o["cp.utag_" + RegExp.$1 + "_" + c] = b[d][c]; | |
} | |
} | |
} | |
for (c in utag.loader.GV((utag.cl && !utag.cl['_all_']) ? utag.cl : b)) { | |
if (c.indexOf("utag_") < 0 && typeof b[c] != "undefined") o["cp." + c] = b[c]; | |
} | |
}, | |
RDqp: function(o, a, b, c){ | |
a = location.search + (location.hash+'').replace("#","&"); | |
if(utag.cfg.lowerqp){a=a.toLowerCase()}; | |
if (a.length > 1) { | |
b = a.substring(1).split('&'); | |
for (a = 0; a < b.length; a++) { | |
c = b[a].split("="); | |
if(c.length>1){ | |
o["qp." + c[0]] = utag.ut.decode(c[1]) | |
} | |
} | |
} | |
}, | |
RDmeta: function(o, a, b, h){ | |
a = document.getElementsByTagName("meta"); | |
for (b = 0; b < a.length; b++) { | |
try{ | |
h = a[b].name || a[b].getAttribute("property") || ""; | |
}catch(e){h="";utag.DB(e)}; | |
if (utag.cfg.lowermeta){h=h.toLowerCase()}; | |
if (h != ""){o["meta." + h] = a[b].content} | |
} | |
}, | |
RDva: function(o){ | |
// Read visitor attributes in local storage | |
var readAttr = function(o, l ){ | |
var a = "", b; | |
a = localStorage.getItem(l); | |
if(!a || a=="{}")return; | |
b = utag.ut.flatten({va : JSON.parse(a)}); | |
utag.ut.merge(o,b,1); | |
} | |
try{ | |
readAttr(o, "tealium_va" ); | |
readAttr(o, "tealium_va_" + o["ut.account"] + "_" + o["ut.profile"] ); | |
}catch(e){ utag.DB(e) } | |
}, | |
RDut: function(o, a){ | |
// Add built-in data types to the data layer for use in mappings, extensions and RDva function. | |
var t = {}; | |
var d = new Date(); | |
var m = ( utag.ut.typeOf(d.toISOString) == "function" ); | |
o["ut.domain"] = utag.cfg.domain; | |
o["ut.version"] = utag.cfg.v; | |
// i.e. "view" or "link" | |
t["tealium_event"] = o["ut.event"] = a || "view"; | |
t["tealium_visitor_id"] = o["ut.visitor_id"]=o["cp.utag_main_v_id"]; | |
t["tealium_session_id"] = o["ut.session_id"]=o["cp.utag_main_ses_id"]; | |
t["tealium_session_number"] = o["cp.utag_main__sn"]; | |
t["tealium_session_event_number"] = o["cp.utag_main__se"]; | |
try{ | |
t["tealium_datasource"] = utag.cfg.datasource; | |
t["tealium_account"] = o["ut.account"] = utag.cfg.utid.split("/")[0]; | |
t["tealium_profile"] = o["ut.profile"] = utag.cfg.utid.split("/")[1]; | |
t["tealium_environment"] = o["ut.env"] = utag.cfg.path.split("/")[6]; | |
}catch(e){ utag.DB(e) } | |
t["tealium_random"] = Math.random().toFixed(16).substring(2); | |
t["tealium_library_name"] = "ut"+"ag.js"; | |
t["tealium_library_version"] = ( utag.cfg.template + "0" ).substring(2); | |
t["tealium_timestamp_epoch"] = Math.floor( d.getTime() / 1000 ); | |
t["tealium_timestamp_utc"] = ( m ? d.toISOString() : ""); | |
// Adjust date to local time | |
d.setHours( d.getHours() - ( d.getTimezoneOffset() / 60 ) ); | |
t["tealium_timestamp_local"] = ( m ? d.toISOString().replace( "Z","" ) : "" ); | |
// Any existing data elements with "tealium_" will not be overwritten | |
utag.ut.merge( o, t, 0 ); | |
}, | |
RDses: function( o, a, c ) { | |
a = (new Date()).getTime(); | |
c = ( a + parseInt( utag.cfg.session_timeout ) ) + ""; | |
// cp.utag_main_ses_id will not be in the data layer when it has expired or this is first page view of all time | |
if ( !o["cp.utag_main_ses_id"] ) { | |
o["cp.utag_main_ses_id"] = a + ""; | |
o["cp.utag_main__ss"] = "1"; | |
o["cp.utag_main__se"] = "1"; | |
o["cp.utag_main__sn"] = ( 1 + parseInt( o["cp.utag_main__sn"] || 0 ) ) + ""; | |
} else { | |
o["cp.utag_main__ss"] = "0"; | |
o["cp.utag_main__se"] = ( 1 + parseInt( o["cp.utag_main__se"] || 0 ) ) + ""; | |
} | |
o["cp.utag_main__pn"] = o["cp.utag_main__pn"] || "1"; | |
o["cp.utag_main__st"] = c; | |
utag.loader.SC( "utag_main", { "_sn": ( o["cp.utag_main__sn"] || 1 ), "_se": o["cp.utag_main__se"], "_ss": o["cp.utag_main__ss"], "_st": c, "ses_id": ( o["cp.utag_main_ses_id"] || a ) + ";exp-session", "_pn": o["cp.utag_main__pn"] + ";exp-session" } ); | |
}, | |
RDpv: function( o ) { | |
if ( typeof utag.pagevars == "function" ) { | |
utag.DB("Read page variables"); | |
utag.pagevars(o); | |
} | |
}, | |
RD: function( o, a ) { | |
utag.DB("utag.loader.RD"); | |
utag.DB(o); | |
utag.loader.RDcp(o); | |
if ( !utag.loader.rd_flag ) { | |
utag.loader.rd_flag = 1; | |
o["cp.utag_main_v_id"] = o["cp.utag_main_v_id"] || utag.ut.vi((new Date()).getTime()); | |
o["cp.utag_main__pn"] = ( 1 + parseInt( o["cp.utag_main__pn"] || 0 ) ) + ""; | |
// the _st value is not-yet-set for first page view so we'll need wait to write in _pn value (which is exp-session) | |
// The SC function expires (removes) cookie values that expired with the session | |
utag.loader.SC( "utag_main", { "v_id": o["cp.utag_main_v_id"] } ); | |
utag.loader.RDses(o); | |
} | |
// first utag.track call for noview should not clear session start (_ss) value | |
if(a && !utag.cfg.noview)utag.loader.RDses(o); | |
utag.loader.RDqp(o); | |
utag.loader.RDmeta(o); | |
utag.loader.RDdom(o); | |
utag.loader.RDut(o, a || "view"); | |
utag.loader.RDpv(o); | |
utag.loader.RDva(o); | |
}, | |
RC: function(a, x, b, c, d, e, f, g, h, i, j, k, l, m, n, o, v, ck, cv, r, s, t) { | |
o = {}; | |
b = ("" + document.cookie != "") ? (document.cookie).split("; ") : []; | |
r = /^(.*?)=(.*)$/; | |
s = /^(.*);exp-(.*)$/; | |
t = (new Date()).getTime(); | |
for (c = 0; c < b.length; c++) { | |
if (b[c].match(r)) { | |
ck = RegExp.$1; | |
cv = RegExp.$2; | |
} | |
e = utag.ut.decode(cv); | |
if (typeof ck!="undefined"){ | |
if (ck.indexOf("ulog") == 0 || ck.indexOf("utag_") == 0) { | |
e = cv.split("$"); | |
g = []; | |
j = {}; | |
for (f = 0; f < e.length; f++) { | |
try{ | |
g = e[f].split(":"); | |
if (g.length > 2) { | |
g[1] = g.slice(1).join(":"); | |
} | |
v = ""; | |
if (("" + g[1]).indexOf("~") == 0) { | |
h = g[1].substring(1).split("|"); | |
for (i = 0; i < h.length; i++) h[i] = utag.ut.decode(h[i]); | |
v = h | |
} else v = utag.ut.decode(g[1]); | |
j[g[0]] = v; | |
}catch(er){utag.DB(er)}; | |
} | |
o[ck] = {}; | |
for (f in utag.loader.GV(j)) { | |
if (utag.ut.typeOf(j[f]) == "array") { | |
n = []; | |
for (m = 0; m < j[f].length; m++) { | |
if (j[f][m].match(s)){ | |
k = (RegExp.$2 == "session") ? (typeof j._st != "undefined" ? j._st : t - 1) : parseInt(RegExp.$2); | |
if (k > t) n[m] = (x == 0) ? j[f][m] : RegExp.$1; | |
} | |
} | |
j[f] = n.join("|"); | |
} else { | |
j[f] = "" + j[f]; | |
if (j[f].match(s)) { | |
k = (RegExp.$2 == "session") ? (typeof j._st != "undefined" ? j._st : t - 1) : parseInt(RegExp.$2); | |
j[f] = (k < t) ? null : (x == 0 ? j[f] : RegExp.$1); | |
} | |
} | |
if (j[f]) o[ck][f] = j[f]; | |
} | |
} else if (utag.cl[ck] || utag.cl['_all_']) { | |
o[ck] = e | |
} | |
} | |
} | |
return (a) ? (o[a] ? o[a] : {}) : o; | |
}, | |
SC: function(a, b, c, d, e, f, g, h, i, j, k, x, v) { | |
if (!a) return 0; | |
if (a=="utag_main" && utag.cfg.nocookie) return 0; | |
v = ""; | |
var date = new Date(); | |
var exp = new Date(); | |
exp.setTime(date.getTime()+(365*24*60*60*1000)); | |
x = exp.toGMTString(); | |
if (c && c == "da") { | |
x = "Thu, 31 Dec 2009 00:00:00 GMT"; | |
} else if (a.indexOf("utag_") != 0 && a.indexOf("ulog") != 0) { | |
if (typeof b != "object") { | |
v = b | |
} | |
} else { | |
d = utag.loader.RC(a, 0); | |
for (e in utag.loader.GV(b)) { | |
f = "" + b[e]; | |
if (f.match(/^(.*);exp-(\d+)(\w)$/)) { | |
g = date.getTime() + parseInt(RegExp.$2) * ((RegExp.$3 == "h") ? 3600000 : 86400000); | |
if (RegExp.$3 == "u") g = parseInt(RegExp.$2); | |
f = RegExp.$1 + ";exp-" + g; | |
} | |
if (c == "i") { | |
if (d[e] == null) d[e] = f; | |
} else if (c == "d") delete d[e]; | |
else if (c == "a") d[e] = (d[e] != null) ? (f - 0) + (d[e] - 0) : f; | |
else if (c == "ap" || c == "au") { | |
if (d[e] == null) d[e] = f; | |
else { | |
if (d[e].indexOf("|") > 0) { | |
d[e] = d[e].split("|") | |
} | |
g = (utag.ut.typeOf(d[e]) == "array") ? d[e] : [d[e]]; | |
g.push(f); | |
if (c == "au") { | |
h = {}; | |
k = {}; | |
for (i = 0; i < g.length; i++) { | |
if (g[i].match(/^(.*);exp-(.*)$/)) { | |
j = RegExp.$1; | |
} | |
if (typeof k[j] == "undefined") { | |
k[j] = 1; | |
h[g[i]] = 1; | |
} | |
} | |
g = []; | |
for (i in utag.loader.GV(h)) { | |
g.push(i); | |
} | |
} | |
d[e] = g | |
} | |
} else d[e] = f; | |
} | |
h = new Array(); | |
for (g in utag.loader.GV(d)) { | |
if (utag.ut.typeOf(d[g]) == "array") { | |
for (c = 0; c < d[g].length; c++) { | |
d[g][c] = encodeURIComponent(d[g][c]) | |
} | |
h.push(g + ":~" + d[g].join("|")) | |
} else h.push((g + ":").replace(/[\,\$\;\?]/g,"") + encodeURIComponent(d[g])) | |
} | |
if (h.length == 0) { | |
h.push(""); | |
x = "" | |
} | |
v = (h.join("$")); | |
} | |
document.cookie = a + "=" + v + ";path=/;domain=" + utag.cfg.domain + ";expires=" + x + (utag.cfg.secure_cookie?";secure":""); | |
return 1 | |
}, | |
LOAD: function(a, b, c, d) { | |
//utag.DB('utag.loader.LOAD:' + a); | |
if(!utag.loader.cfg){ | |
return | |
} | |
if(this.ol==0){ | |
if(utag.loader.cfg[a].block && utag.loader.cfg[a].cbf){ | |
this.f[a] = 1; | |
delete utag.loader.bq[a]; | |
} | |
for(b in utag.loader.GV(utag.loader.bq)){ | |
if(utag.loader.cfg[a].load==4 && utag.loader.cfg[a].wait==0){ | |
utag.loader.bk[a]=1; | |
utag.DB("blocked: "+ a); | |
} | |
utag.DB("blocking: " + b); | |
return; | |
} | |
utag.loader.INIT(); | |
return; | |
} | |
utag.DB('utag.loader.LOAD:' + a); | |
if (this.f[a] == 0) { | |
this.f[a] = 1; | |
if(utag.cfg.noview!=true){ | |
if(utag.loader.cfg[a].send){ | |
utag.DB("SENDING: "+a); | |
try{ | |
if (utag.loader.sendq.pending > 0 && utag.loader.sendq[a]) { | |
utag.DB("utag.loader.LOAD:sendq: "+a); | |
while( d = utag.loader.sendq[a].shift() ) { | |
utag.DB(d); | |
utag.sender[a].send(d.event, utag.handler.C(d.data)); | |
utag.loader.sendq.pending--; | |
} | |
} else { | |
utag.sender[a].send('view',utag.handler.C(utag.data)); | |
} | |
utag.rpt['s_' + a] = 0; | |
} catch (e) { | |
utag.DB(e); | |
utag.rpt['s_' + a] = 1; | |
} | |
} | |
} | |
if(utag.loader.rf==0)return; | |
for (b in utag.loader.GV(this.f)) { | |
if (this.f[b] == 0 || this.f[b] == 2) return | |
} | |
utag.loader.END(); | |
} | |
}, | |
EV: function(a, b, c, d) { | |
if (b == "ready") { | |
if(!utag.data){ | |
try { | |
utag.cl = {'_all_': 1}; | |
utag.loader.initdata(); | |
utag.loader.RD(utag.data); | |
}catch(e){ utag.DB(e) }; | |
} | |
if ( (document.attachEvent || utag.cfg.dom_complete) ? document.readyState === "complete" : document.readyState !== "loading" ) setTimeout(c, 1); | |
else { | |
utag.loader.ready_q.push(c); | |
var RH; | |
if(utag.loader.ready_q.length<=1){ | |
if (document.addEventListener) { | |
RH = function() { | |
document.removeEventListener("DOMContentLoaded", RH, false); | |
utag.loader.run_ready_q() | |
}; | |
if(!utag.cfg.dom_complete)document.addEventListener("DOMContentLoaded", RH, false); | |
window.addEventListener("load", utag.loader.run_ready_q, false); | |
} else if (document.attachEvent) { | |
RH = function() { | |
if (document.readyState === "complete") { | |
document.detachEvent("onreadystatechange", RH); | |
utag.loader.run_ready_q() | |
} | |
}; | |
document.attachEvent("onreadystatechange", RH); | |
window.attachEvent("onload", utag.loader.run_ready_q); | |
} | |
} | |
} | |
} else { | |
if (a.addEventListener) { | |
a.addEventListener(b, c, false) | |
} else if (a.attachEvent) { | |
a.attachEvent(((d == 1) ? "" : "on") + b, c) | |
} | |
} | |
}, | |
END: function(b, c, d, e, v, w){ | |
if(this.ended){return}; | |
this.ended=1; | |
utag.DB("loader.END"); | |
b = utag.data; | |
// add the default values for future utag.link/view calls | |
if(utag.handler.base && utag.handler.base!='*'){ | |
e = utag.handler.base.split(","); | |
for (d = 0; d < e.length; d++) { | |
if (typeof b[e[d]] != "undefined") utag.handler.df[e[d]] = b[e[d]] | |
} | |
}else if (utag.handler.base=='*'){ | |
utag.ut.merge(utag.handler.df,b,1); | |
} | |
utag.rpt['r_0']="t"; | |
for(var r in utag.loader.GV(utag.cond)){ | |
utag.rpt['r_'+r]=(utag.cond[r])?"t":"f"; | |
} | |
utag.rpt.ts['s'] = new Date(); | |
##UTSENDCOMPLETE## | |
v = utag.cfg.path; | |
// both .tiqcdn.com and .tiqcdn.cn supported | |
w = v.indexOf(".tiqcdn."); | |
if(w>0 && b["cp.utag_main__ss"]==1 && !utag.cfg.no_session_count)utag.ut.loader({src:v.substring(0,v.indexOf("/ut"+"ag/")+6)+"tiqapp/ut"+"ag.v.js?a="+utag.cfg.utid+(utag.cfg.nocookie?"&nocookie=1":"&cb="+(new Date).getTime()),id:"tiqapp"}) | |
if(utag.cfg.noview!=true)utag.handler.RE('view',b,"end"); | |
utag.handler.INIT(); | |
} | |
}, | |
DB: function(a, b) { | |
// return right away if we've already checked the cookie | |
if(utag.cfg.utagdb===false){ | |
return; | |
}else if(typeof utag.cfg.utagdb=="undefined"){ | |
b = document.cookie+''; | |
utag.cfg.utagdb=((b.indexOf('utagdb=true') >= 0)?true:false); | |
} | |
if(utag.cfg.utagdb===true){ | |
var t; | |
if(utag.ut.typeOf(a) == "object"){ | |
t=utag.handler.C(a) | |
}else{ | |
t=a | |
} | |
utag.db_log.push(t); | |
try{if(!utag.cfg.noconsole)console.log(t)}catch(e){} | |
} | |
}, | |
RP: function(a, b, c) { | |
if (typeof a != 'undefined' && typeof a.src != 'undefined' && a.src != '') { | |
b = []; | |
for (c in utag.loader.GV(a)) { | |
if (c != 'src') b.push(c + '=' + escape(a[c])) | |
} | |
this.dbi.push((new Image()).src = a.src + '?utv=' + utag.cfg.v + '&utid=' + utag.cfg.utid + '&' + (b.join('&'))) | |
} | |
}, | |
view: function(a,c,d) { | |
return this.track({event:'view', data:a || {}, cfg:{cb:c,uids:d}}) | |
}, | |
link: function(a,c,d) { | |
return this.track({event:'link', data:a || {}, cfg:{cb:c,uids:d}}) | |
}, | |
track: function(a,b,c,d,e) { | |
// CHANGE | |
if (window.TMSHelper && TMSHelper.dbgActive && "undefined" !== typeof a && window.console && window.console.log) { | |
// output data layer to console as submitted for Hit by Application before any Tealium changes to it | |
if (a.event) { | |
console.log("--- utag." + a.event + " Call: ---"); | |
} | |
console.log("Data Layer submitted to Tealium:"); | |
console.log(JSON.stringify(a.data, null, 4)); | |
} | |
// END CHANGE | |
a = a || {}; | |
if (typeof a == "string") { | |
a = { event: a, data: b || {}, cfg:{cb:c,uids:d} } | |
} | |
// track called directly also supports a 3rd option where first param (a) is data layer and second param (b) is cb function | |
for(e in utag.loader.GV(utag.o)){ | |
utag.o[e].handler.trigger(a.event || "view", a.data || a, a.cfg || {cb:b,uids:c}) | |
} | |
a.cfg = a.cfg || {cb:b}; | |
if(typeof a.cfg.cb == "function")a.cfg.cb(); | |
return true | |
}, | |
handler: { | |
base: "##UTBASEVARIABLES##", | |
df: {}, | |
o: {}, | |
send: {}, | |
iflag: 0, | |
INIT: function(a, b, c) { | |
utag.DB('utag.handler.INIT'); | |
if(utag.initcatch){ | |
utag.initcatch=0; | |
return | |
} | |
this.iflag = 1; | |
a = utag.loader.q.length; | |
if (a > 0) { | |
utag.DB("Loader queue"); | |
for (b = 0; b < a; b++) { | |
c = utag.loader.q[b]; | |
utag.handler.trigger(c.a, c.b, c.c) | |
} | |
} | |
//##UTABSOLUTELAST## | |
}, | |
test: function() { | |
return 1 | |
}, | |
// reset and run load rules | |
LR: function(b){ | |
utag.DB("Load Rules"); | |
for(var d in utag.loader.GV(utag.cond)){ | |
utag.cond[d]=false; | |
} | |
utag.DB(b); | |
utag.loader.loadrules(b); | |
utag.DB(utag.cond); | |
utag.loader.initcfg(); | |
// use the OPTOUTMULTI cookie value to override load rules | |
utag.loader.OU(); | |
for(var r in utag.loader.GV(utag.cond)){ | |
utag.rpt['r_'+r]=(utag.cond[r])?"t":"f"; | |
} | |
}, | |
// The third param "c" is a string that defines the location i.e. "blr" == before load rules | |
RE:function(a,b,c,d,e,f,g){ | |
if(c!="alr" && !this.cfg_extend){ | |
return 0; | |
} | |
utag.DB("RE: "+c); | |
if(c=="alr")utag.DB("All Tags EXTENSIONS"); | |
utag.DB(b); | |
if (c === "alr" && TMSHelper.dbgActive) { | |
console.log("Data Layer after 'All Tags' Extensions in 'After Load Rules' scope have run, " + | |
"==> right before Mapping to Tags starts!"); | |
console.log(b); | |
} | |
if(typeof this.extend != "undefined"){ | |
g=0; | |
for (d = 0; d < this.extend.length; d++) { | |
try { | |
/* Extension Attributes */ | |
e=0; | |
if(typeof this.cfg_extend!="undefined"){ | |
f=this.cfg_extend[d]; | |
if(typeof f.count == "undefined")f.count=0; | |
if(f[a]==0 || (f.once==1 && f.count>0) || f[c]==0){ | |
e=1 | |
}else{ | |
if(f[c]==1){g=1}; | |
f.count++ | |
} | |
} | |
if(e!=1){ | |
this.extend[d](a, b); | |
utag.rpt['ex_' + d] = 0 | |
} | |
} catch (er) { | |
utag.DB(er); | |
utag.rpt['ex_' + d] = 1; | |
utag.ut.error({e:er.message,s:utag.cfg.path+'utag.js',l:d,t:'ge'}); | |
} | |
} | |
utag.DB(b); | |
return g; | |
} | |
}, | |
trigger: function(a, b, c, d, e, f) { | |
utag.DB('trigger:'+a+(c && c.uids?":"+c.uids.join(","):"")); | |
b = b || {}; | |
utag.DB(b); | |
if (!this.iflag) { | |
utag.DB("trigger:called before tags loaded"); | |
for (d in utag.loader.f) { | |
if (!(utag.loader.f[d] === 1)) utag.DB('Tag '+d+' did not LOAD') | |
} | |
utag.loader.q.push({ | |
a: a, | |
b: utag.handler.C(b), | |
c: c | |
}); | |
return; | |
} | |
// update all values for AJAX pages | |
utag.ut.merge(b,this.df,0); | |
utag.loader.RD( b, a ); | |
// clearing noview flag after the RD function call | |
utag.cfg.noview = false; | |
function sendTag(a, b, d){ | |
try { | |
if(typeof utag.sender[d]!="undefined"){ | |
utag.DB("SENDING: "+d); | |
utag.sender[d].send(a, utag.handler.C(b)); | |
utag.rpt['s_' + d] = 0; | |
}else if (utag.loader.cfg[d].load!=2){ | |
// utag.link calls can load in new tags | |
utag.loader.sendq[d] = utag.loader.sendq[d] || []; | |
utag.loader.sendq[d].push({"event":a, "data":utag.handler.C(b)}); | |
utag.loader.sendq.pending++; | |
utag.loader.AS({id : d, load : 1}); | |
} | |
}catch (e) {utag.DB(e)} | |
} | |
// utag.track( { event : "view", data: {myvar : "myval" }, cfg: { uids : [1,2,10] } } ); | |
if(c && c.uids){ | |
this.RE(a,b,"alr"); | |
for(f=0;f<c.uids.length;f++){ | |
d=c.uids[f]; | |
// bypass load rules, but still check the OPTOUTMULTI cookie before firing | |
if (!utag.loader.OU(utag.loader.cfg[d].tid)) { | |
sendTag(a, b, d); | |
} | |
} | |
}else if(utag.cfg.load_rules_ajax){ | |
this.RE(a,b,"blr"); | |
// process load rules based on current data layer | |
this.LR(b); | |
this.RE(a,b,"alr"); | |
for(f = 0; f < utag.loader.cfgsort.length; f++){ | |
d = utag.loader.cfgsort[f]; | |
if(utag.loader.cfg[d].load && utag.loader.cfg[d].send){ | |
sendTag(a, b, d); | |
} | |
} | |
}else{ | |
// legacy behavior | |
this.RE(a,b,"alr"); | |
for (d in utag.loader.GV(utag.sender)) { | |
sendTag(a, b, d); | |
} | |
} | |
this.RE(a,b,"end"); | |
}, | |
// "sort-of" copy | |
C: function(a, b, c) { | |
b = {}; | |
for (c in utag.loader.GV(a)) { | |
if(utag.ut.typeOf(a[c]) == "array"){ | |
b[c] = a[c].slice(0) | |
}else{ | |
// objects are still references to the original (not copies) | |
b[c] = a[c] | |
} | |
} | |
return b | |
} | |
}, | |
ut:{ | |
pad: function(a,b,c,d){ | |
a=""+((a-0).toString(16));d='';if(b>a.length){for(c=0;c<(b-a.length);c++){d+='0'}}return ""+d+a | |
}, | |
vi: function(t,a,b){ | |
if(!utag.v_id){ | |
a=this.pad(t,12);b=""+Math.random();a+=this.pad(b.substring(2,b.length),16);try{a+=this.pad((navigator.plugins.length?navigator.plugins.length:0),2);a+=this.pad(navigator.userAgent.length,3);a+=this.pad(document.URL.length,4);a+=this.pad(navigator.appVersion.length,3);a+=this.pad(screen.width+screen.height+parseInt((screen.colorDepth)?screen.colorDepth:screen.pixelDepth),5)}catch(e){utag.DB(e);a+="12345"};utag.v_id=a; | |
} | |
return utag.v_id | |
}, | |
hasOwn: function(o, a) { | |
return o != null && Object.prototype.hasOwnProperty.call(o, a) | |
}, | |
isEmptyObject: function(o, a) { | |
for (a in o) { | |
if (utag.ut.hasOwn(o,a))return false | |
} | |
return true | |
}, | |
isEmpty: function(o) { | |
var t = utag.ut.typeOf(o); | |
if ( t == "number" ){ | |
return isNaN(o) | |
}else if ( t == "boolean" ){ | |
return false | |
}else if ( t == "string" ){ | |
return o.length === 0 | |
}else return utag.ut.isEmptyObject(o) | |
}, | |
typeOf: function(e) { | |
return ({}).toString.call(e).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); | |
}, | |
flatten: function(o){ | |
// stop when arriving at a string, array, boolean, number (float or integer) | |
var a = {}; | |
function r(c, p) { | |
if (Object(c) !== c || utag.ut.typeOf(c) == "array") { | |
a[p] = c; | |
} else { | |
if(utag.ut.isEmptyObject(c)){ | |
//a[p] = {}; | |
}else{ | |
for (var d in c) { | |
r(c[d], p ? p+"."+d : d); | |
} | |
} | |
} | |
} | |
r(o, ""); | |
return a; | |
}, | |
merge: function(a, b, c, d) { | |
if(c){ | |
for(d in utag.loader.GV(b)){ | |
a[d] = b[d] | |
} | |
}else{ | |
for(d in utag.loader.GV(b)){ | |
if(typeof a[d]=="undefined")a[d] = b[d] | |
} | |
} | |
}, | |
decode: function(a, b) { | |
b = ""; | |
try{b = decodeURIComponent(a)}catch(e){utag.DB(e)}; | |
if (b == ""){b = unescape(a)}; | |
return b | |
}, | |
encode: function(a, b) { | |
b = ""; | |
try{b = encodeURIComponent(a)}catch(e){utag.DB(e)}; | |
if (b == ""){b = escape(a)}; | |
return b | |
}, | |
error: function(a, b, c){ | |
if(typeof utag_err!="undefined"){ | |
utag_err.push(a) | |
} | |
}, | |
loader: function(o, a, b, c, l, m) { | |
utag.DB(o); | |
a=document; | |
if (o.type=="iframe") { | |
// if an iframe of same id already exists, remove and add again (to keep DOM clean and avoid impacting browser history) | |
m = a.getElementById( o.id ); | |
if ( m && m.tagName == "IFRAME" ) { | |
m.parentNode.removeChild(m); | |
} | |
b = a.createElement("iframe"); | |
o.attrs = o.attrs || {}; | |
utag.ut.merge( o.attrs, { "height" : "1", "width" : "1", "style" : "display:none" } , 0 ); | |
}else if (o.type=="img"){ | |
utag.DB("Attach img: "+o.src); | |
b = new Image(); | |
}else{ | |
b = a.createElement("script");b.language="javascript";b.type="text/javascript";b.async=1;b.charset="utf-8"; | |
} | |
if(o.id){b.id=o.id}; | |
for( l in utag.loader.GV(o.attrs) ){ | |
b.setAttribute( l, o.attrs[l] ) | |
} | |
b.setAttribute("src", o.src); | |
if (typeof o.cb=="function") { | |
if(b.addEventListener) { | |
b.addEventListener("load",function(){o.cb()},false); | |
}else { | |
// old IE support | |
b.onreadystatechange=function(){if(this.readyState=='complete'||this.readyState=='loaded'){this.onreadystatechange=null;o.cb()}}; | |
} | |
} | |
if(typeof o.error=="function"){ | |
utag.loader.EV(b, "error", o.error); | |
} | |
if ( o.type != "img" ) { | |
l = o.loc || "head"; | |
c = a.getElementsByTagName(l)[0]; | |
if (c) { | |
utag.DB("Attach to "+l+": "+o.src); | |
if (l == "script") { | |
c.parentNode.insertBefore(b, c); | |
} else { | |
c.appendChild(b) | |
} | |
} | |
} | |
} | |
} | |
}; | |
utag.o['##UTLOADERID##']=utag; | |
utag.cfg = { | |
template : "ut4.48.", | |
// Enable load rules ajax feature by default | |
load_rules_ajax: true, | |
load_rules_at_wait: false, | |
lowerqp: false, | |
noconsole: false, | |
//noview: ##UTNOVIEW##, | |
session_timeout: ##UTSESSIONTIMEOUT##, | |
readywait: ##UTREADYWAIT##, | |
noload: ##UTNOLOAD##, | |
domain: ##UTDOMAIN##, | |
datasource: "##UTDATASOURCE##".replace("##"+"UTDATASOURCE##",""), | |
secure_cookie: ("##UTSECURECOOKIE##".replace("##"+"UTSECURECOOKIE##","")==="true")?true:false, | |
path: "##UTPATH##", | |
utid: "##UTID##" | |
}; | |
utag.cfg.v = utag.cfg.template + "##UTVERSION##"; | |
##UTGEN## | |
if(typeof utag_cfg_ovrd!='undefined'){for(utag._i in utag.loader.GV(utag_cfg_ovrd))utag.cfg[utag._i]=utag_cfg_ovrd[utag._i]}; | |
utag.loader.PINIT = function(a,b,c){ | |
utag.DB("Pre-INIT"); | |
if (utag.cfg.noload) { | |
return; | |
} | |
try { | |
// Initialize utag.data | |
this.GET(); | |
// Even if noview flag is set, we still want to load in tags and have them ready to fire | |
// blr = "before load rules" | |
if(utag.handler.RE('view',utag.data,"blr")){ | |
utag.handler.LR(utag.data); | |
} | |
}catch(e){utag.DB(e)}; | |
// process 'blocking' tags (tags that need to run first) | |
a=this.cfg; | |
c=0; | |
for (b in this.GV(a)) { | |
// external .js files (currency converter tag) are blocking | |
if(a[b].block == 1 || (a[b].load>0 && (typeof a[b].src!='undefined'&&a[b].src!=''))){ | |
a[b].block = 1; | |
c=1; | |
this.bq[b]=1; | |
} | |
} | |
if(c==1) { | |
for (b in this.GV(a)) { | |
if(a[b].block){ | |
// handle case of bundled and blocking (change 4 to 1) | |
// (bundled tags that do not have a .src should really never be set to block... they just run first) | |
a[b].id=b; | |
if(a[b].load==4)a[b].load=1; | |
a[b].cb=function(){ | |
var d=this.uid; | |
utag.loader.cfg[d].cbf=1; | |
utag.loader.LOAD(d) | |
}; | |
this.AS(a[b]); | |
} | |
} | |
} | |
if(c==0)this.INIT(); | |
}; | |
utag.loader.INIT = function(a, b, c, d, e) { | |
utag.DB('utag.loader.INIT'); | |
if (this.ol == 1) return -1; | |
else this.ol = 1; | |
// The All Tags scope extensions run after blocking tags complete | |
// The noview flag means to skip these Extensions (will run later for manual utag.view call) | |
if(utag.cfg.noview!=true)utag.handler.RE('view',utag.data,"alr"); | |
utag.rpt.ts['i'] = new Date(); | |
d = this.cfgsort; | |
// TODO: Publish engine should sort the bundled tags first.. | |
for (a=0;a<d.length;a++){ | |
e = d[a]; | |
b = this.cfg[e]; | |
b.id = e; | |
if(b.block != 1){ | |
// do not wait if the utag.cfg.noview flag is set and the tag is bundled | |
if (utag.loader.bk[b.id] || ((utag.cfg.readywait||utag.cfg.noview) && b.load==4)){ | |
this.f[b.id]=0; | |
utag.loader.LOAD(b.id) | |
}else if (b.wait == 1 && utag.loader.rf == 0) { | |
utag.DB('utag.loader.INIT: waiting ' + b.id); | |
this.wq.push(b) | |
this.f[b.id]=2; | |
}else if (b.load>0){ | |
utag.DB('utag.loader.INIT: loading ' + b.id); | |
this.lq.push(b); | |
this.AS(b); | |
} | |
} | |
} | |
if (this.wq.length > 0) utag.loader.EV('', 'ready', function(a) { | |
if(utag.loader.rf==0){ | |
utag.DB('READY:utag.loader.wq'); | |
utag.loader.rf=1; | |
utag.loader.WQ(); | |
} | |
}); | |
else if(this.lq.length>0)utag.loader.rf=1; | |
else if(this.lq.length==0)utag.loader.END(); | |
return 1 | |
}; | |
##UTDOMREADYEXTENSIONS## | |
if(utag.cfg.readywait || utag.cfg.waittimer){ | |
utag.loader.EV('', 'ready', function(a) { | |
if(utag.loader.rf==0){ | |
utag.loader.rf=1; | |
utag.cfg.readywait=1; | |
utag.DB('READY:utag.cfg.readywait'); | |
setTimeout(function(){utag.loader.PINIT()}, utag.cfg.waittimer || 1); | |
} | |
}) | |
}else{ | |
utag.loader.PINIT() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment