/**
* @class
* @classdesc Plugin to track audio and video spots.
* @name TvTracking
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param parent {object} Instance of the Tag used
* @public
*/
window['ATInternet']['Tracker']['Plugins']['TvTracking'] = function (parent) {
'use strict';
var _this = this;
var _config = {};
var _set_cookie_method = '';
var _get_cookie_method = '';
var _cookieSpotValuePersist = null;
var _cookieVisitValue = null;
var _cookieVisitDirectValue = null;
var _cookieVisitPersistValue = null;
var _customTvTObject = {};
var _done = false;
var _timeout = false;
/**
* Define labels to use for unique persistence.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _defineUniquePersistence = function () {
_set_cookie_method = 'set' + (_config.domainAttribution ? '' : 'Private');
_get_cookie_method = 'get' + (_config.domainAttribution ? '' : 'Private');
};
/**
* Helper to use the plugin Cookies.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param method {string} Method to call in the plugin
* @param params {Array} Parameters to transmit
* @return {*}
* @private
*/
var _pluginCookie = function (method, params) {
var ret = null;
parent['plugins']['exec']('Cookies', method, params, function (data) {
ret = data;
});
return ret;
};
/**
* Check if given object is empty, if not it returns false else true.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param object {object}
* @return {boolean}
* @private
*/
var _objectIsEmptyOrWithNullProperties = function (object) {
for (var p in object) {
if (object.hasOwnProperty(p) && object[p] !== null) {
return false;
}
}
return true;
};
/**
* Check if a cookie is present and with type object, if not it creates it and returns true,
* if present but with another type it returns false.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param name {string} Name of the cookie you need to check
* @param options {object} Options of the cookie to create
* @return {boolean}
* @private
*/
var _checkCookie = function (name, options) {
var temp = _pluginCookie(_get_cookie_method, [name]);
if (temp !== null) {
return (typeof temp === 'object' && !(temp instanceof Array));
}
else {
_pluginCookie(_set_cookie_method, [name, {}, options]);
return true;
}
};
/**
* Set Page context.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _setPageContext = function () {
var contextPageObject = parent.getContext('page') || {};
var contextCustomObject = contextPageObject['customObject'] || {};
contextCustomObject.TvTracking = _customTvTObject;
contextPageObject.customObject = contextCustomObject;
// Set new custom object in page context
parent.setContext('page', contextPageObject);
parent.processSpecificDispatchEventFor('tvTracking');
};
/**
* Get persistent and direct spot values from cookies.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _getCookieValues = function () {
_cookieSpotValuePersist = _pluginCookie(_get_cookie_method, ['attvtreman']);
_cookieVisitValue = _pluginCookie(_get_cookie_method, ['attvtsession']);
_cookieVisitDirectValue = _pluginCookie(_get_cookie_method, [['attvtsession', 'direct']]);
_cookieVisitPersistValue = _pluginCookie(_get_cookie_method, [['attvtsession', 'remanent']]);
};
/**
* Check the validity of partner object.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param partnerObject {object} Object containing partner properties
* @return {boolean}
* @private
*/
var _isValidPartnerObject = function (partnerObject) {
return !!(typeof partnerObject !== 'undefined' && typeof partnerObject['channel'] !== 'undefined' && partnerObject['channel'] !== 'undefined');
};
/**
* Check time format and calculate retention period.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param time {string} Value to test
* @return {boolean}
* @private
*/
var _isValidDateTime = function (time) {
if (time && typeof time === 'string') {
var spot = new Date(_convertDateFromISO(time));
var now = new Date();
return ((now >= spot) && ((now - spot) <= _config.retentionPeriod * 60 * 1000)); // spot is managed for 5mn
}
return false;
};
/**
* Convert string from ISO to Date format.
* @memberof ATInternet.Tracker.Plugins.TvTracking#
* @function
* @param str {string} Value to convert
* @return {date|number}
* @private
*/
var _convertDateFromISO = function (str) {
var date, regex = /^(\d{4}\-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/, res = regex.exec(str) || [];
if (res[1]) {
date = res[1].split(/\D/);
for (var i = 0; i < date.length; i++) {
date[i] = parseInt(date[i], 10) || 0;
}
date[1] -= 1;
date = new Date(Date.UTC.apply(Date, date));
if (!date.getDate()) {
return NaN;
}
if (res[5]) {
var tz = (parseInt(res[5], 10) * 60);
if (res[6]) {
tz += parseInt(res[6], 10);
}
if (res[4] === '+') {
tz *= -1;
}
if (tz) {
date.setUTCMinutes(date.getUTCMinutes() + tz);
}
}
return date;
}
return NaN;
};
/**
* Init TvTracking configuration.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _initConfig = function () {
// Set visitLifetime value from global configuration.
parent.setConfig('visitLifetime', dfltGlobalCfg.visitLifetime, true);
// Set specific plugin configuration.
// If global configuration already exists, set only undefined properties.
parent.configPlugin('TvTracking', dfltPluginCfg || {}, function (newConf) {
_config = newConf;
});
};
/**
* Init TvTracking info object.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _initInfoTvT = function () {
// Create final TvTracking object
_customTvTObject.info = {
version: _config.version,
message: '',
errors: []
};
};
/**
* Run TvTracking global processing.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _run = function () {
parent.addSpecificDispatchEventFor('tvTracking');
var callback = function (error) {
if (!_timeout) {
_done = true;
if (error !== null) {
_setScriptError();
}
_setDataTvT();
_setPageContext();
}
};
ATInternet.Utils.loadScript({url: _config.url + '&rn=' + Math.random()}, callback);
var errorTimeout = function () {
if (!_done) {
_setTimeoutError();
_setDataTvT();
_setPageContext();
}
};
setTimeout(errorTimeout, _config.timeout);
};
/**
* Set TvTracking script error.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _setScriptError = function () {
_customTvTObject.info.errors.push('noScript');
};
/**
* Set TvTracking timeout error.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _setTimeoutError = function () {
_customTvTObject.info.errors.push('timeout');
_timeout = true;
};
/**
* Set TvTracking data.
* @memberOf ATInternet.Tracker.Plugins.TvTracking#
* @function
* @private
*/
var _setDataTvT = function () {
// Set input values.
var isDataPresent = false;
var spotDirectValue = {};
var spotPersistentValue = {};
var partnerObject = window[_config.tvtrackingcustom];
// Get properties from partner object.
if (_isValidPartnerObject(partnerObject)) {
var time = partnerObject['time'];
if (_isValidDateTime(time)) {
isDataPresent = true;
}
else {
_customTvTObject.info.errors.push('timeError');
}
_customTvTObject.info.message = time;
}
else {
if (typeof partnerObject === 'undefined') {
_customTvTObject.info.errors.push('noData');
}
else if (typeof partnerObject['channel'] === 'undefined') {
_customTvTObject.info.errors.push('noChannel');
}
else if (partnerObject['channel'] === 'undefined') {
_customTvTObject.info.message = 'channelUndefined';
}
}
// New visit.
if (_cookieVisitValue === null) {
// Direct data.
if (isDataPresent) {
spotDirectValue.direct = partnerObject;
}
// Persistent data.
if (_cookieSpotValuePersist !== null) {
spotPersistentValue.remanent = _cookieSpotValuePersist;
}
// Last persistence or First one but without persistent data from cookie.
if ((_config.lastPersistence === true) || (_cookieSpotValuePersist === null)) {
// Store Direct data in persistent cookie.
var dateExp = new Date();
dateExp.setDate(dateExp.getDate() + _config.lifetime);
if (isDataPresent) {
_pluginCookie(_set_cookie_method, ['attvtreman', spotDirectValue.direct, {
path: _config.path,
end: dateExp
}]);
}
}
}
else {
spotDirectValue.direct = _cookieVisitDirectValue;
spotPersistentValue.remanent = _cookieVisitPersistValue;
}
// Set session cookie for the visit.
if (_checkCookie('attvtsession', {
path: _config.path,
session: parent.getConfig('visitLifetime') * 60
}, _set_cookie_method, _get_cookie_method)) {
if (_cookieVisitValue === null) {
_pluginCookie(_set_cookie_method, [['attvtsession', 'direct'], spotDirectValue.direct]);
_pluginCookie(_set_cookie_method, [['attvtsession', 'remanent'], spotPersistentValue.remanent]);
}
}
// Add value 'direct' if spotDirectValue is not empty.
if ((typeof spotDirectValue === 'object') && !_objectIsEmptyOrWithNullProperties(spotDirectValue)) {
_customTvTObject.direct = spotDirectValue.direct;
}
// Add value 'remanent' if spotDirectValue is not empty.
if ((typeof spotPersistentValue === 'object') && !_objectIsEmptyOrWithNullProperties(spotPersistentValue)) {
_customTvTObject.remanent = spotPersistentValue.remanent;
}
// Update session cookie on trigger 'Tracker:Hit:Sent:Ok'.
parent.onTrigger('Tracker:Hit:Sent:Ok', function () {
_pluginCookie(_get_cookie_method, ['attvtsession']);
});
// Add cookie error message if attvtsession cookie is null.
if (_pluginCookie(_get_cookie_method, ['attvtsession', true]) === null) {
_customTvTObject.info.errors.push('cookieError');
}
/* @if debug */
parent.debug('TvTracking:tvTracking:set', 'DEBUG', 'method ended', _customTvTObject);
/* @endif */
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.TvTracking TvTracking}] Tags to track audio and video spots.
* @name tvTracking
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#tvTracking.set}
* @public
*/
parent['tvTracking'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.TvTracking TvTracking}] Set TvTracking parameters.
* @alias tvTracking.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @example
* <pre><code class="javascript">tag.tvTracking.set();
* </code></pre>
* @public
*/
parent['tvTracking']['set'] = _this['set'] = function () {
// Register helper to final call in order to send messages.
parent.dispatchSubscribe('tvTracking');
_initConfig();
_initInfoTvT();
/* @if test */
var acceptCookie = false;
/* @endif */
if (!parent.getConfig('disableCookie')) {
/* @if test */
acceptCookie = true;
/* @endif */
_defineUniquePersistence();
_getCookieValues();
if (!_cookieVisitValue) {
if (_config.url && typeof _config.url === 'string') {
_run();
}
else {
_customTvTObject.info.message = 'noURLSet';
_setDataTvT();
_setPageContext();
}
}
else {
_customTvTObject.info.message = 'sessionAlreadyActive';
_setDataTvT();
_setPageContext();
}
}
else {
_customTvTObject.info.message = 'disableCookie:true';
_setPageContext();
}
/* @if test */
return acceptCookie;
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.TvTracking TvTracking}] Will be called by tracker.dispatch if any TvTracking has been set.
* @alias tvTracking.onDispatch
* @memberof! ATInternet.Tracker.Tag#
* @function
* @private
*/
parent['tvTracking']['onDispatch'] = _this['onDispatch'] = function () {
if (!parent.dispatchSubscribed('page')) {
/* @if debug */
parent.debug('TvTracking:tvTracking:onDispatch:Error', 'WARNING', 'TvTracking data are not sent without page information (use page.set())');
/* @endif */
}
};
// For unit tests on private elements !!!
/* @if test */
_this._defineUniquePersistence = _defineUniquePersistence;
_this._pluginCookie = _pluginCookie;
_this._objectIsEmptyOrWithNullProperties = _objectIsEmptyOrWithNullProperties;
_this._checkCookie = _checkCookie;
_this._setPageContext = _setPageContext;
_this._getCookieValues = _getCookieValues;
_this._isValidPartnerObject = _isValidPartnerObject;
_this._isValidDateTime = _isValidDateTime;
_this._convertDateFromISO = _convertDateFromISO;
_this._initConfig = _initConfig;
_this._initInfoTvT = _initInfoTvT;
_this._run = _run;
_this._setScriptError = _setScriptError;
_this._setTimeoutError = _setTimeoutError;
_this._setDataTvT = _setDataTvT;
_this.getCookieMethods = function () {
_this._set_cookie_method = _set_cookie_method;
_this._get_cookie_method = _get_cookie_method;
};
/* @endif */
};
window['ATInternet']['Tracker']['addPlugin']('TvTracking');