/**
* @class
* @classdesc Plugin used to manage event sending.
* @name Event
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param parent {object} Instance of the Tag used
* @public
*/
window['ATInternet']['Tracker']['Plugins']['Event'] = function (parent) {
'use strict';
var _config = {};
var _debug = {
level: 'DEBUG',
messageEnd: 'method ended',
messageCall: 'method called'
};
/**
* Get events data.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param eventArray {array} Object from tag or event context
* @return {String}
* @private
*/
var _getEventsData = function (eventArray) {
var events = [];
for (var i = 0; i < eventArray.length; i++) {
for (var key in eventArray[i]) {
if (eventArray[i].hasOwnProperty(key)) {
events.push({'name': key, 'data': eventArray[i][key]});
}
}
}
return ATInternet.Utils.jsonSerialize(events);
};
/**
* Set events param.
* @memberof ATInternet.Tracker.Plugins.Event#
* @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';
parent.setParam('events', _getEventsData(eventArray), {
hitType: [_origin],
encode: true,
truncate: true,
separator: ','
});
};
/**
* Get chapter context depending on Tracker configuration.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param pageContext {object} Page context
* @return {object}
* @private
*/
var _getChapterContext = function (pageContext) {
var chapterContext = {};
var ignoreEmpty = parent.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))) {
chapterContext[chapterKey] = chapterLabel;
}
}
return chapterContext;
};
/**
* Get context data.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param pageContext {object} Page context
* @return {String}
* @private
*/
var _getContextData = function (pageContext) {
var pageObject = _getChapterContext(pageContext);
pageObject['$'] = pageContext.name || '';
var level2Key = 'level2';
var level2Value = pageContext.level2 || '';
if (level2Value !== '' && !isNaN(level2Value)) {
level2Key = 'level2_id';
level2Value = Number(level2Value);
}
var siteObject = {};
siteObject[level2Key] = level2Value;
return ATInternet.Utils.jsonSerialize([{'data': {'page': pageObject, 'site': siteObject}}]);
};
/**
* Set context param.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param pageContext {object} Page context
* @param origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @private
*/
var _setContextParam = function (pageContext, origin) {
var _origin = origin || 'event';
parent.setParam('context', _getContextData(pageContext), {
hitType: [_origin],
encode: true
});
};
/**
* Check if type of tag is object.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param tagObject {object} Object from tag
* @return {boolean}
* @private
*/
var _isObject = function (tagObject) {
return ((typeof tagObject === 'object') && !(tagObject instanceof Array));
};
/**
* Merge context with tag object.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @param tagContext {object} Object from event context
* @param tagData {object} 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 (_isObject(tagContext) && _isObject(tagData)) {
mergedContext = ATInternet.Utils.completeFstLevelObj(tagContext, tagData, true);
} else {
mergedContext = tagData;
}
return mergedContext;
};
/**
* Launch plugin when all dependencies are loaded.
* @memberof ATInternet.Tracker.Plugins.Event#
* @function
* @private
*/
var _init = function () {
var dependencies = ['Utils'];
parent.plugins.waitForDependencies(dependencies, function () {
// Set specific plugin configuration.
// If global configuration already exists, set only undefined properties.
parent.configPlugin('Event', dfltPluginCfg || {}, function (newConf) {
_config = newConf;
});
});
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] 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
*/
parent.event = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] 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
*/
parent.event.reset = function (origin) {
var _origin = origin || 'event';
var contextEventObject = parent.getContext(_origin) || [];
/* @if debug */
parent.debug('Event:event:reset', _debug.level, _debug.messageCall, {
'context': contextEventObject,
'origin': _origin
});
/* @endif */
parent.setContext(_origin, undefined);
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] Tagging method for event sending (helper).
* @alias event.send
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagType {String} Event type
* @param tagData {object} Event value
* @param tagConfig {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
*/
parent.event.send = function (tagType, tagData, tagConfig) {
var preservePropagation = true;
var _origin = 'event';
if (tagConfig && tagConfig.origin) {
_origin = tagConfig.origin;
}
var eventObject = {};
eventObject[tagType] = tagData;
var hitObject = {};
// 1. Set &col=2 parameter
hitObject[_config.hitParameter] = {
_value: _config.hitValue,
_options: {
multihit: true
}
};
// 2. Set Page context
var pageContext = parent.getContext('page');
if (typeof pageContext !== 'undefined') {
hitObject.context = {
_value: _getContextData(pageContext),
_options: {
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() && parent.getConfig('preview')) {
hitObject.pvw = 1;
}
// Manage click propagation
var domEventObject = null;
if (tagConfig && tagConfig.hasOwnProperty('event')) {
domEventObject = tagConfig.event || window.event;
}
if (!ATInternet.Utils.isTabOpeningAction(domEventObject) && tagConfig && tagConfig.elem) {
preservePropagation = parent.techClicks.manageClick(tagConfig.elem, domEventObject);
}
parent.manageSend(function () {
var callback;
if (tagConfig) {
callback = tagConfig.callback;
}
parent.sendHit(hitObject, [['hitType', [_origin]]], callback, null);
});
/* @if debug */
parent.debug('Event:event:send', _debug.level, _debug.messageEnd, {
'name': tagType,
'data': tagData,
'origin': _origin
});
/* @endif */
return preservePropagation;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] Set events.
* @alias event.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagType {String} Event type
* @param tagData {object} Event value
* @param tagKey {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
*/
parent.event.set = function (tagType, tagData, tagKey, origin) {
var _origin = origin || 'event';
// 1. Set &col=2 parameter
parent.setParam(_config.hitParameter, _config.hitValue, {multihit: true, hitType: [_origin]});
// Register helper to final call in order to send messages.
parent.dispatchSubscribe(_origin);
var contextEventObject = parent.getContext(_origin) || [];
var foundType = false;
for (var i = 0; i < contextEventObject.length; i++) {
if (contextEventObject[i][tagType]) {
foundType = true;
if (tagKey) {
if (_isObject(contextEventObject[i][tagType])) {
contextEventObject[i][tagType][tagKey] = _mergeValues(contextEventObject[i][tagType][tagKey], tagData);
}
} else {
contextEventObject[i][tagType] = _mergeValues(contextEventObject[i][tagType], tagData);
}
}
}
if (!foundType) {
var defaultValue = {};
if (tagKey) {
defaultValue[tagType] = {};
defaultValue[tagType][tagKey] = tagData;
} else {
defaultValue[tagType] = tagData;
}
contextEventObject.push(defaultValue);
}
parent.setContext(_origin, contextEventObject);
/* @if debug */
var data;
if (tagKey) {
data = {};
data[tagKey] = tagData;
} else {
data = tagData;
}
parent.debug('Event:event:set', _debug.level, _debug.messageEnd, {
'name': tagType,
'data': data,
'origin': _origin
});
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] Add events.
* @alias event.add
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagType {String} Event type
* @param tagData {object} 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
*/
parent.event.add = function (tagType, tagData, origin) {
var _origin = origin || 'event';
var contextEventObject = parent.getContext(_origin) || [];
var defaultValue = {};
defaultValue[tagType] = tagData;
contextEventObject.push(defaultValue);
parent.setContext(_origin, contextEventObject);
/* @if debug */
parent.debug('Event:event:add', _debug.level, _debug.messageEnd, {
'name': tagType,
'data': tagData,
'origin': _origin
});
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Event Event}] 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 origin {String} Type origin. Ex: 'salesTracker', 'click', etc.
* @private
*/
parent.event.onDispatch = function (callback, origin) {
var _origin = origin || 'event';
// 2. Set Page context
var pageContext = parent.getContext('page');
if (typeof pageContext !== 'undefined') {
_setContextParam(pageContext, _origin);
}
// 3. Set Event context (truncable param at the end)
var contextEventObject = parent.getContext(_origin);
if (typeof contextEventObject !== 'undefined') {
_setEventsParam(contextEventObject, _origin);
}
parent.setContext(_origin, undefined);
// Safari preview.
if (ATInternet.Utils.isPreview() && parent.getConfig('preview')) {
parent.setParam('pvw', 1, {hitType: [_origin]});
}
parent.manageSend(function () {
parent.sendHit(null, [['hitType', [_origin]]], callback, null);
});
};
_init();
// For unit tests on private elements !!!
/* @if test */
var _this = this;
_this._getEventsData = _getEventsData;
_this._setEventsParam = _setEventsParam;
_this._getChapterContext = _getChapterContext;
_this._getContextData = _getContextData;
_this._setContextParam = _setContextParam;
_this._isObject = _isObject;
_this._mergeValues = _mergeValues;
_this._init = _init;
/* @endif */
};
window['ATInternet']['Tracker']['addPlugin']('Event');