Skip to content

Instantly share code, notes, and snippets.

@loldenburg
Last active October 30, 2021 13:45
Show Gist options
  • Save loldenburg/d83d7a5caf5c6640bebc3e5608de7a0f to your computer and use it in GitHub Desktop.
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
//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