Skip to content

Instantly share code, notes, and snippets.

@jde
Created May 28, 2013 19:58
Show Gist options
  • Save jde/5665628 to your computer and use it in GitHub Desktop.
Save jde/5665628 to your computer and use it in GitHub Desktop.
NYTD = {};
NYTD.EventTracker = (function () {
'use strict';
var etHost;
var lastEventTime = 0;
var nextCallbackNum = 0;
var wtMetaExcludes = {
'wt.z_nyts': 1,
'wt.z_nytd': 1,
'wt.z_ref': 1,
'wt.z_rmid': 1
};
if (!NYTD.env || NYTD.env === "production") {
etHost = "et.nytimes.com";
} else if (NYTD.env === "staging") {
etHost = "et.stg.use1.nytimes.com";
} else {
etHost = "et.dev.use1.nytimes.com";
}
var buildUrl = function (url, params) {
var key;
var qs = '';
for (key in params) if (params.hasOwnProperty(key)) {
qs += (qs ? '&' : '') + key + '=' + encodeURIComponent(params[key]);
}
if (qs.length > 0) {
return url + '?' + qs;
} else {
return url;
}
};
var copyObject = function (obj) {
var key;
var objCopy = {};
for (key in obj) if (obj.hasOwnProperty(key)) {
objCopy[key] = obj[key];
}
return objCopy;
};
var extractMetaTags = function (obj) {
var name, nameLower, content, i;
var tags = document.getElementsByTagName('meta');
obj = obj || {};
for (i = 0; i < tags.length; i += 1) {
name = tags[i].getAttribute('name');
content = tags[i].getAttribute('content');
if (typeof name === 'string' && typeof content === 'string') {
nameLower = name.toLowerCase();
if (nameLower.substr(0, 3) === 'wt.' &&
!wtMetaExcludes[nameLower]) {
obj[name] = content;
}
}
}
return obj;
};
return function () {
var trackNow, agentId;
var that = this;
var datumId = null;
var parentDatumId = null;
var firedFirstEvent = false;
var scripts = [];
var queue = [];
var newData = [];
if (this instanceof NYTD.EventTracker === false) {
return new NYTD.EventTracker();
}
trackNow = function (evt, options) {
var scriptElem, oldScriptElem;
var callbackNum = nextCallbackNum;
nextCallbackNum += 1;
NYTD.EventTracker['cb' + callbackNum] = function (result) {
var i;
delete NYTD.EventTracker['cb' + callbackNum];
if (result.status && result.status === 'OK') {
if (!datumId && options.buffer) {
datumId = result.datumId;
for (i = 0; i < queue.length; i += 1) {
trackNow(queue[i].evt, queue[i].options);
}
}
if (!agentId) {
agentId = result.agentId;
}
if (options.callback) {
options.callback(null, result);
}
} else {
if (options.callback) {
options.callback(new Error('Event tracking failed'),
result);
}
}
};
evt = copyObject(evt);
if (!options.buffer) {
evt.instant = '1';
}
evt.callback = 'NYTD.EventTracker.cb' + callbackNum;
if (datumId && options.buffer) {
evt.datumId = datumId;
}
if (options.sendMeta) {
extractMetaTags(evt);
}
if (agentId) {
evt.agentId = agentId;
}
scriptElem = document.createElement('script');
scriptElem.src = buildUrl((document.location.protocol || 'http:') +
'//'+etHost+'/', evt);
document.body.appendChild(scriptElem);
scripts.push(scriptElem);
if (scripts.length > 5) {
oldScriptElem = scripts.shift();
document.body.removeChild(oldScriptElem);
}
};
this.track = function (evt, options) {
options = options || {};
if (!options.background) {
lastEventTime = (new Date()).valueOf();
}
if(evt.subject !== 'page' && this.getParentDatumId() !== null) {
evt.parentDatumId = this.getParentDatumId();
}
if(newData.length > 0) {
var newDataItem,
key;
for (var i = 0; i < newData.length; i++) {
newDataItem = newData[i];
for (key in newDataItem) if (newDataItem.hasOwnProperty(key)) {
evt[key] = newDataItem[key];
}
newData = []; // empty the array out for future usage
}
}
if (!options.buffer) {
trackNow(evt, options);
} else if (datumId || !firedFirstEvent) {
firedFirstEvent = true;
trackNow(evt, options);
} else {
queue.push({
evt: copyObject(evt),
options: copyObject(options)
});
}
};
this.updateData = function (oArg) {
if(oArg instanceof Array) {
newData = newData.concat(oArg)
} else if(typeof oArg === 'object') {
newData.push(oArg);
}
};
this.hasTrackedEventRecently = function () {
return ((new Date()).valueOf() - lastEventTime) < 960000;
};
this.getDatumId = function () {
return datumId;
};
this.getParentDatumId = function() {
if(parentDatumId === null &&
NYTD.pageEventTracker && NYTD.pageEventTracker.getDatumId() !== null) {
parentDatumId = NYTD.pageEventTracker.getDatumId();
}
return parentDatumId;
};
this.pixelTrack = function (evt, qs) {
var imgsrc, validEvt, validQs;
validEvt = (function (e) {
var k;
if (typeof e !== 'object') {
return false;
}
for (k in e) if (e.hasOwnProperty(k)) {
return true;
}
return false;
}(evt));
validQs = (typeof qs === 'string' && qs !== '');
if (!validEvt && !validQs) {
return;
}
imgsrc = (document.location.protocol || 'http:') + '//' + etHost +
'/pixel';
if (validEvt) {
imgsrc = buildUrl(imgsrc, evt);
}
if (validQs) {
imgsrc += ((imgsrc.indexOf('?') === -1 ? '?' : '&') + qs);
}
new Image().src = imgsrc;
};
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment