/**
* @class
* @classdesc Plugin used to manage event sending.
* @name EventRoot
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param tag {object} Instance of the Tag used
* @public
*/
ATInternet.Tracker.Plugins.EventRoot = function (tag) {
'use strict';
var _config = {};
var _debug = {
level: 'DEBUG',
messageEnd: 'method ended',
messageCall: 'method called'
};
/**
* Get events data.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param eventArray {array} Object from tag or event context
* @return {String}
* @private
*/
var _getEventsData = function (eventArray) {
var events = [];
var data;
for (var i = 0; i < eventArray.length; i++) {
for (var key in eventArray[i]) {
if (eventArray[i].hasOwnProperty(key)) {
if (ATInternet.Utils.isObject(eventArray[i][key])) {
data = ATInternet.Utils.objectToLowercase(eventArray[i][key]);
} else {
data = eventArray[i][key];
}
events.push({
'name': key.toLowerCase(),
'data': data
});
}
}
}
return ATInternet.Utils.jsonSerialize(events);
};
/**
* Set events param.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param eventArray {array} Object from tag or event context
* @param origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @private
*/
var _setEventsParam = function (eventArray, origin) {
var _origin = origin || 'event';
tag.setParam('events', _getEventsData(eventArray), {
hitType: [_origin],
encode: true,
truncate: true,
separator: ','
});
};
/**
* Get 'page' data from page context depending on Tracker configuration.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param pageContext {Object} Page context
* @return {Object}
* @private
*/
var _getPageValues = function (pageContext) {
// Page
var pageValues = {};
if (pageContext.name) {
pageValues['$'] = pageContext.name;
}
// Chapters
var ignoreEmpty = tag.getConfig('ignoreEmptyChapterValue');
var chapterLabel = '';
var chapterKey = '';
for (var i = 1; i <= 3; i++) {
chapterKey = 'chapter' + i;
chapterLabel = pageContext[chapterKey] || '';
if ((ignoreEmpty && chapterLabel) || (!ignoreEmpty && pageContext.hasOwnProperty(chapterKey))) {
pageValues[chapterKey] = chapterLabel;
}
}
// url
if (pageContext.url) {
pageValues['url'] = pageContext.url;
}
return pageValues;
};
/**
* Get 'site' data from page context depending on Tracker configuration.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param pageContext {Object} Page context
* @return {Object}
* @private
*/
var _getSiteValues = function (pageContext) {
var siteValues = {};
// Level2
if (typeof pageContext.level2 === 'string') {
var level2Trim = ATInternet.Utils.trim(pageContext.level2);
if (level2Trim.length > 0) {
if (!isNaN(level2Trim)) {
siteValues['level2_id'] = Number(level2Trim);
} else {
siteValues['level2'] = level2Trim;
}
}
} else if (typeof pageContext.level2 === 'number') {
siteValues['level2_id'] = pageContext.level2;
}
return siteValues;
};
/**
* Get context data.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param pageContext {object} Page context
* @return {String}
* @private
*/
var _getContextData = function (pageContext, campaignsEventsContext) {
var contextData = '';
var pageObject = {};
var siteObject = {};
if (typeof pageContext !== 'undefined') {
pageObject = _getPageValues(pageContext);
siteObject = _getSiteValues(pageContext);
}
var data = {};
if (!ATInternet.Utils.isEmptyObject(pageObject)) {
data.page = pageObject;
}
if (!ATInternet.Utils.isEmptyObject(siteObject)) {
data.site = siteObject;
}
// Complete all events with campaigns_events context
if (typeof campaignsEventsContext !== 'undefined') {
data.src = campaignsEventsContext;
}
if (!ATInternet.Utils.isEmptyObject(data)) {
contextData = ATInternet.Utils.jsonSerialize([{'data': data}]);
}
return contextData;
};
/**
* Set context param.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param pageContext {object} Page context
* @param origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @private
*/
var _setContextParam = function (pageContext, campaignsEventsContext, origin) {
var _origin = origin || 'event';
var contextData = _getContextData(pageContext, campaignsEventsContext);
if (contextData !== '') {
tag.setParam('context', contextData, {
truncate: true,
hitType: [_origin],
encode: true
});
}
};
/**
* Merge context with tag object.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @param tagContext {object} Object from event context
* @param tagData {object|Array} Object from tag
* @return {object|array|string}
* @private
*/
var _mergeValues = function (tagContext, tagData) {
var mergedContext;
if (tagContext instanceof Array && tagData instanceof Array) {
mergedContext = tagContext.concat(tagData);
} else if (ATInternet.Utils.isObject(tagContext) && ATInternet.Utils.isObject(tagData)) {
mergedContext = ATInternet.Utils.completeFstLevelObj(tagContext, tagData, true);
} else {
mergedContext = tagData;
}
return mergedContext;
};
/**
* Init plugin.
* @memberof ATInternet.Tracker.Plugins.EventRoot#
* @function
* @private
*/
var _init = function () {
var dependencies = ['Utils'];
tag.plugins.waitForDependencies(dependencies, function () {
// Set specific plugin configuration.
// If global configuration already exists, set only undefined properties.
tag.configPlugin('EventRoot', dfltPluginCfg || {}, function (newConf) {
_config = newConf;
});
});
};
// **************** EVENT (public technical helpers) ***************** //
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Tags to manage event sending.
* @name event
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} reset Tag helper, see details here {@link ATInternet.Tracker.Tag#event.reset}
* @property {function} send Tag helper, see details here {@link ATInternet.Tracker.Tag#event.send}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#event.set}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#event.add}
* @public
*/
tag.event = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Reset event context.
* @alias event.reset
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @example
* <pre><code class="javascript">tag.event.reset();
* </code></pre>
* @public
*/
tag.event.reset = function (origin) {
var _origin = origin || 'event';
var contextEventObject = tag.getContext(_origin) || [];
/* @if debug */
tag.debug('EventRoot:event:reset', _debug.level, _debug.messageCall, {
'context': contextEventObject,
'origin': _origin
});
/* @endif */
tag.delContext(_origin);
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Tagging method for event sending (helper).
* @alias event.send
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param name {String} Event name
* @param data {object|Array} Event value
* @param options {object} (optional) Technical configuration of the tag
* @examples
* <pre><code class="javascript">
tag.event.send('product.display',
{
's:placement': 'homepage_slider',
'a:product': [{
's:id': 'id1',
's:name': 'name1',
's:brand': 'brand1',
'f:original_price': 16.50,
'f:price': 14.00,
's:currency': 'EUR',
'b:stock': 1,
's:category1': 'category1',
's:category2': 'category2',
's:category3': 'category3',
's:category4': 'category4',
's:category5': 'category5',
's:category6': 'category6',
'n:position': 1
}]
},
{
elem: this, // (optional) Tagged DOM element
event: event, // (optional) JavaScript event (prevent event propagation)
callback: callback, // (optional) function to execute
origin: 'event', // (optional) Type origin. Ex: 'salesTracker', 'click', etc.
});
* </code></pre>
* @public
*/
tag.event.send = function (name, data, options) {
var preservePropagation = true;
var elementType = '';
var _origin = 'event';
if (options && options.origin) {
_origin = options.origin;
}
var eventObject = {};
eventObject[name] = data;
var hitObject = {};
// 1. Set &col=2 parameter
hitObject[_config.hitParameter] = {
_value: _config.hitValue,
_options: {
multihit: true
}
};
// 2. Set Page context
var pageContext = tag.getContext('page');
var campaignsEventsContext = tag.getContext('campaigns_events');
if (typeof pageContext !== 'undefined' || typeof campaignsEventsContext !== 'undefined') {
hitObject.context = {
_value: _getContextData(pageContext, campaignsEventsContext),
_options: {
truncate: true,
encode: true
}
};
}
// 3. Set events parameter (truncable param at the end)
hitObject.events = {
_value: _getEventsData([eventObject]),
_options: {
encode: true,
truncate: true,
separator: ','
}
};
// Set Safari preview.
if (ATInternet.Utils.isPreview() && tag.getConfig('preview')) {
hitObject.pvw = 1;
}
// Manage click propagation
var domEventObject = null;
if (options && options.hasOwnProperty('event')) {
domEventObject = options.event || window.event;
}
if (!ATInternet.Utils.isTabOpeningAction(domEventObject) && options && options.elem) {
var manage = tag.techClicks.manageClick(options.elem, domEventObject);
preservePropagation = manage.preservePropagation;
elementType = manage.elementType;
}
tag.manageSend(function () {
var callback;
if (options) {
callback = options.callback;
}
tag.sendHit(hitObject, [['hitType', [_origin]]], callback, null, elementType);
});
/* @if debug */
tag.debug('EventRoot:event:send', _debug.level, _debug.messageEnd, {
'name': name,
'data': data,
'origin': _origin
});
/* @endif */
return preservePropagation;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Set events.
* @alias event.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param name {String} Event name
* @param data {object|Array} Event value
* @param [key] {object} Event key
* @param [origin] {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @examples
* <pre><code class="javascript">
tag.event.set('product.display', {
's:placement': 'homepage_slider',
'a:product': [{
's:id': 'id1',
's:name': 'name1',
's:brand': 'brand1',
'f:original_price': 16.50,
'f:price': 14.00,
's:currency': 'EUR',
'b:stock': 1,
's:category1': 'category1',
's:category2': 'category2',
's:category3': 'category3',
's:category4': 'category4',
's:category5': 'category5',
's:category6': 'category6',
'n:position': 1
}]
});
* </code></pre>
* @public
*/
tag.event.set = function (name, data, key, origin) {
var _origin = origin || 'event';
// 1. Set &col=2 parameter
tag.setParam(_config.hitParameter, _config.hitValue, {multihit: true, hitType: [_origin]});
// Register helper to final call in order to send messages.
tag.dispatchSubscribe(_origin);
var contextEventObject = tag.getContext(_origin) || [];
var foundType = false;
for (var i = 0; i < contextEventObject.length; i++) {
if (contextEventObject[i][name]) {
foundType = true;
if (key) {
if (ATInternet.Utils.isObject(contextEventObject[i][name])) {
contextEventObject[i][name][key] = _mergeValues(contextEventObject[i][name][key], data);
}
} else {
contextEventObject[i][name] = _mergeValues(contextEventObject[i][name], data);
}
}
}
if (!foundType) {
var defaultValue = {};
if (key) {
defaultValue[name] = {};
defaultValue[name][key] = data;
} else {
defaultValue[name] = data;
}
contextEventObject.push(defaultValue);
}
tag.setContext(_origin, contextEventObject);
/* @if debug */
var debugData = {};
if (key) {
debugData[key] = data;
} else {
debugData = data;
}
tag.debug('EventRoot:event:set', _debug.level, _debug.messageEnd, {
'name': name,
'data': debugData,
'origin': _origin
});
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Add events.
* @alias event.add
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param name {String} Event name
* @param data {object|Array} Event value
* @param [origin] {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @examples
* <pre><code class="javascript">
tag.event.add('product.display', {
's:placement': 'homepage_slider',
'a:product': [{
's:id': 'id1',
's:name': 'name1',
's:brand': 'brand1',
'f:original_price': 16.50,
'f:price': 14.00,
's:currency': 'EUR',
'b:stock': 1,
's:category1': 'category1',
's:category2': 'category2',
's:category3': 'category3',
's:category4': 'category4',
's:category5': 'category5',
's:category6': 'category6',
'n:position': 1
}]
});
* </code></pre>
* @public
*/
tag.event.add = function (name, data, origin) {
var _origin = origin || 'event';
var contextEventObject = tag.getContext(_origin) || [];
var defaultValue = {};
defaultValue[name] = data;
contextEventObject.push(defaultValue);
tag.setContext(_origin, contextEventObject);
/* @if debug */
tag.debug('EventRoot:event:add', _debug.level, _debug.messageEnd, {
'name': name,
'data': data,
'origin': _origin
});
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.EventRoot EventRoot}] Will be called by tracker.dispatch if any event has been set.
* @alias event.onDispatch
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param callback {function} Callback to execute
* @param elementType {string} Element type (mailto, form, redirection)
* @param origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @private
*/
tag.event.onDispatch = function (callback, elementType, origin) {
var _origin = origin || 'event';
// 2. Set Page /campaigns_events context
var pageContext = tag.getContext('page');
var campaignsEventsContext = tag.getContext('campaigns_events');
if (typeof pageContext !== 'undefined' || typeof campaignsEventsContext !== 'undefined') {
_setContextParam(pageContext, campaignsEventsContext, _origin);
}
// 3. Set Event context (truncable param at the end)
var contextEventObject = tag.getContext(_origin);
if (typeof contextEventObject !== 'undefined') {
_setEventsParam(contextEventObject, _origin);
}
tag.delContext(_origin);
// Safari preview.
if (ATInternet.Utils.isPreview() && tag.getConfig('preview')) {
tag.setParam('pvw', 1, {hitType: [_origin]});
}
tag.manageSend(function () {
tag.sendHit(null, [['hitType', [_origin]]], callback, null, elementType);
});
};
_init();
// For unit tests on private elements !!!
/* @if test */
var _this = this;
_this._getEventsData = _getEventsData;
_this._setEventsParam = _setEventsParam;
_this._getPageValues = _getPageValues;
_this._getSiteValues = _getSiteValues;
_this._getContextData = _getContextData;
_this._setContextParam = _setContextParam;
_this._mergeValues = _mergeValues;
_this._init = _init;
/* @endif */
};
ATInternet.Tracker.addPlugin('EventRoot');