/**
* @class
* @name Page
* @memberof ATInternet.Tracker.Plugins
* @type {function}
* @param parent {object} Instance of the Tag used
* @description
* This plugin allows you to define page tag data :
* <ul>
* <li><b>Page values</b>: to declare name, level2, chapters and custom object parameters.
* <li><b>Site variables</b>: to associate information specific to your activity (interface language, load times, number of articles per page, etc.) with your site.</li>
* <li><b>Page variables</b>: to evaluate the performance of specific pages of your site, notably those offering fields to be filled out.</li>
* <li><b>Dynamic labels</b>: to track the history of a page whose content has been modified.</li>
* <li><b>Tags (or keywords)</b>: to define the theme(s) of the content your users visit.</li>
* <li><b>Custom tree structure</b>: to obtain a completely customised view of all your traffic to completely match your analysis criteria.</li>
* </ul>
* It also processes Campaigns and Internal Search contexts.
* @public
*/
window['ATInternet']['Tracker']['Plugins']['Page'] = function (parent) {
"use strict";
var self = this;
var _confPage = {
dynamicLabel: {
properties: ['pageId', 'chapterLabel', 'update'],
parameters: ['pid', 'pchap', 'pidt']
},
customVars: {
properties: ['page', 'site'],
parameters: ['f', 'x']
}
};
/**
* Get page name with chapters.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param tagObject {object} Page object containing properties to use
* @returns {string}
* @private
*/
var _getFullName = function(tagObject){
var name = tagObject['name'];
parent['exec']('Utils', 'manageChapters', [tagObject, 'chapter', 3], function(data){
name = data + (name ? name : '');
});
return name;
};
/**
* Set context with tag object value or default value.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param context {object} Context property to process
* @param tag {object} Tag property to use
* @param def {string} Default value to use if context value is not defined
* @returns {string}
* @private
*/
var _magic = function(context, tag, def) {
if (tag) {
context = tag;
} else if (!context && typeof def !== 'undefined') {
context = def;
}
return context;
};
/**
* Set value if property has been declared.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param context {object} Context to process
* @param tag {object} Page object containing properties to use
* @param key {string} Name of the property to set
* @private
*/
var _setDeclaredProperty = function(context, tag, key) {
if(tag.hasOwnProperty(key)) {
context[key] = _magic(context[key], tag[key]);
}
};
/**
* Manage send depending on Safari previewing and Chrome/IE prerendering.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param callback {function} Function to execute when not in prerendering mode or on "visibilityChangeEvent"
* @private
*/
var _manageSend = function(callback){
if (!ATInternet.Utils.isPreview() || parent.getConfig('preview')) {
if (!ATInternet.Utils.isPrerender(function (event) {
callback(event);
})) {
callback();
}
}
};
/**
* Add site or page indicators to a local buffer object or global tag buffer.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param buffer {object} Local buffer from helper send
* @param object {object} Object from tag or page context
* @param isLocal {boolean} True if local buffer, false otherwise
* @private
*/
var _setIndicatorVariables = function (buffer, object, isLocal) {
if (object) {
var props = _confPage.customVars.properties;
var params = _confPage.customVars.parameters;
for (var i = 0; i < props.length; i++) {
if (object.hasOwnProperty(props[i]) && object[props[i]]) {
for (var p in object[props[i]]) {
if (object[props[i]].hasOwnProperty(p)) {
if (isLocal) {
buffer[params[i] + p] = object[props[i]][p];
}
else {
parent.setParam(params[i] + p, object[props[i]][p]);
}
}
}
}
}
}
};
/**
* Add dynamic label to a local buffer object or global tag buffer.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param buffer {object} Local buffer from helper send
* @param object {object} Object from tag or page context
* @param isLocal {boolean} True if local buffer, false otherwise
* @private
*/
var _setDynamicLabel = function (buffer, object, isLocal) {
if (object) {
parent['exec']('Utils', 'manageChapters', [object, 'chapter', 3], function (data) {
if (data) {
object['chapterLabel'] = data.replace(/::$/gi, '');
}
});
var props = _confPage.dynamicLabel.properties;
var params = _confPage.dynamicLabel.parameters;
for (var i = 0; i < params.length; i++) {
if (object.hasOwnProperty(props[i])) {
if (isLocal) {
buffer[params[i]] = object[props[i]];
}
else {
parent.setParam(params[i], object[props[i]]);
}
}
}
}
};
/**
* Add tags (keywords) to a local buffer object or global tag buffer.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param buffer {object} Local buffer from helper send
* @param object {object} Object from tag or page context
* @param isLocal {boolean} True if local buffer, false otherwise
* @private
*/
var _setTags = function(buffer, object, isLocal){
if(object && object['keywords'] instanceof Array){
var tabLenght = object['keywords'].length;
if(tabLenght > 0){
var str = '';
for(var i = 0 ; i < tabLenght ; i++){
str += '[' + object['keywords'][i] + ']' + (i<(tabLenght-1) ? '|' : '');
}
if (isLocal) {
buffer['tag'] = str;
}
else {
parent.setParam('tag', str);
}
}
}
};
/**
* Add a custom tree structure to a local buffer object or global tag buffer.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param buffer {object} Local buffer from helper send
* @param object {object} Object from tag or page context
* @param isLocal {boolean} True if local buffer, false otherwise
* @private
*/
var _setCustomTreeStructure = function(buffer, object, isLocal){
if(object){
var str = '';
var checkCategory = function(property){
return (property?property:'0');
};
str += checkCategory(object['category1']) + '-';
str += checkCategory(object['category2']) + '-';
str += checkCategory(object['category3']);
if (isLocal) {
buffer['ptype'] = str;
}
else {
parent.setParam('ptype', str);
}
}
};
/**
* Add campaign variables to a local buffer object or global tag buffer.
* @memberof ATInternet.Tracker.Plugins.Page#
* @function
* @param buffer {object} Local buffer from helper send
* @param object {object} Object from campaign context
* @param isLocal {boolean} True if local buffer, false otherwise
* @private
*/
var _setCampaignsVariables = function (buffer, object, isLocal) {
if (object) {
for (var key in object) {
if (object.hasOwnProperty(key) && typeof object[key] !== 'undefined') {
if (isLocal) {
buffer[key] = object[key];
}
else {
parent.setParam(key, object[key]);
}
}
}
}
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tags to associate page and site variables specific to your activity.
* @name customVars
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#customVars.set}
* @public
*/
parent['customVars'] = self['customVars'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Set page and site variables.
* @alias customVars.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 2 properties : site, page
* @example
* <pre><code class="javascript">tag.customVars.set({
* site: {
* 1: 'site1',
* 5: 'site5',
* 20: 'site20'
* },
* page: {
* 1: 'page1',
* 5: 'page5',
* 20: 'page20'
* }
* });
* </code></pre>
* @public
*/
parent['customVars']['set'] = self['customVars']['set'] = function (tagObject) {
var _getCustomVars = function(target, source) {
if(target) {
if (source) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
target[key] = ATInternet.Utils.completeFstLevelObj(target[key], source[key], true);
}
}
}
}
else{
target = source;
}
return target;
};
var contextPageObject = parent.getContext('page') || {};
//Indicators
contextPageObject.customVars = _getCustomVars(contextPageObject.customVars, tagObject);
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:customVars:set','DEBUG','method ended',tagObject);
/* @endif */
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tags to track the history of a page whose content has been modified.
* @name dynamicLabel
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#dynamicLabel.set}
* @public
*/
parent['dynamicLabel'] = self['dynamicLabel'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Set dynamic label.
* @alias dynamicLabel.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 5 properties : pageId, chapter1, chapter2, chapter3, update
* @example
* <pre><code class="javascript">tag.dynamicLabel.set({
* pageId: '123456',
* chapter1: 'mychapter1',
* chapter2: 'mychapter2',
* chapter3: 'mychapter3',
* update: '200910031045'
* });
* </code></pre>
* @public
*/
parent['dynamicLabel']['set'] = self['dynamicLabel']['set'] = function (tagObject) {
var contextPageObject = parent.getContext('page') || {};
contextPageObject.dynamicLabel = ATInternet.Utils.completeFstLevelObj(contextPageObject.dynamicLabel, tagObject, true);
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:dynamicLabel:set','DEBUG','method ended',tagObject);
/* @endif */
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tags to define the theme(s) of the content your users visit.
* @name tags
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#tags.set}
* @public
*/
parent['tags'] = self['tags'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Set keywords.
* @alias tags.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 1 property : keywords
* @example
* <pre><code class="javascript">tag.tags.set({
* keywords: ['tag','Key']
* });
* </code></pre>
* @public
*/
parent['tags']['set'] = self['tags']['set']= function(tagObject){
var contextPageObject = parent.getContext('page') || {};
contextPageObject.tags = ATInternet.Utils.completeFstLevelObj(contextPageObject.tags, tagObject, true);
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:tags:set','DEBUG','method ended',tagObject);
/* @endif */
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tags to obtain a completely customised view of all your traffic.
* @name customTreeStructure
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#customTreeStructure.set}
* @public
*/
parent['customTreeStructure'] = self['customTreeStructure'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Set custom tree structure.
* @alias customTreeStructure.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 3 properties : category1, category2, category3
* @example
* <pre><code class="javascript">tag.customTreeStructure.set({
* mycategory1: 1,
* mycategory2: 2,
* mycategory3: 3
* });
* </code></pre>
* @public
*/
parent['customTreeStructure']['set'] = self['customTreeStructure']['set']= function(tagObject){
var contextPageObject = parent.getContext('page') || {};
contextPageObject.customTreeStructure = ATInternet.Utils.completeFstLevelObj(contextPageObject.customTreeStructure, tagObject, true);
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:customTreeStructure:set','DEBUG','method ended',tagObject);
/* @endif */
};
/**
* [Object added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tags to manage a page.
* @name page
* @memberof ATInternet.Tracker.Tag
* @inner
* @type {object}
* @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#page.set}
* @property {function} send Tag helper, see details here {@link ATInternet.Tracker.Tag#page.send}
* @property {function} reset Tag helper, see details here {@link ATInternet.Tracker.Tag#page.reset}
* @public
*/
parent['page'] = {};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Reset page context.
* @alias page.reset
* @memberof! ATInternet.Tracker.Tag#
* @function
* @example
* <pre><code class="javascript">tag.page.reset();
* </code></pre>
* @public
*/
parent['page']['reset'] = self['reset'] = function () {
parent.setContext('page', undefined);
/* @if debug */
parent.debug('Page:page:reset','DEBUG','method ended');
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Set page properties.
* @alias page.set
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 5 properties : name, chapter1, chapter2, chapter3, customObject
* @example
* <pre><code class="javascript">tag.page.set({
* name: 'pageName',
* chapter1: 'mychapter1',
* chapter2: 'mychapter2',
* chapter3: 'mychapter3',
* customObject: {
* one: 1,
* two: 2
* }
* });
* </code></pre>
* @public
*/
parent['page']['set'] = self['set'] = function (tagObject) {
parent.dispatchSubscribe('page');
var contextPageObject = parent.getContext('page') || {};
contextPageObject.name = _magic(contextPageObject.name, tagObject['name'], '');
contextPageObject.level2 = _magic(contextPageObject.level2, tagObject['level2'], '');
//Cas particulier: Dans le cas des chapitres, on ajoute les propriétés dans le contexte de page ssi elles ont été déclarées explicitement par l'utilisateur.
//Explication: La méthode Utils de gestion des chapitres créée un chapitre vide si le paramètre existe et que sa valeur est undefined.
_setDeclaredProperty(contextPageObject, tagObject, 'chapter1');
_setDeclaredProperty(contextPageObject, tagObject, 'chapter2');
_setDeclaredProperty(contextPageObject, tagObject, 'chapter3');
//customObject
contextPageObject.customObject = ATInternet.Utils.completeFstLevelObj(contextPageObject.customObject, tagObject['customObject'], true);
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:page:set','DEBUG','method ended',tagObject);
/* @endif */
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Tagging method for page (helper).
* @alias page.send
* @memberof! ATInternet.Tracker.Tag#
* @function
* @param tagObject {object} 5 properties : name, chapter1, chapter2, chapter3, customObject
* @example
* <pre><code class="javascript">tag.page.send({
* name: 'pageName',
* chapter1: 'mychapter1',
* chapter2: 'mychapter2',
* chapter3: 'mychapter3',
* customObject: {
* one: 1,
* two: 2
* },
* customVars: {
* page: {
* 1: 'page1',
* 5: 'page5',
* 20: 'page20'
* },
* site: {
* 1: 'site1',
* 5: 'site5',
* 20: 'site20'
* }
* },
* dynamicLabel: {
* pageId: '123456',
* chapter1: 'mychapter1',
* chapter2: 'mychapter2',
* chapter3: 'mychapter3',
* update: '200910031045'
* },
* tags: {
* keywords: ['tag','Key']
* },
* customTreeStructure: {
* category1: mycategory1,
* category2: mycategory2,
* category3: mycategory3
* }
* });
* </code></pre>
* @public
*/
parent['page']['send'] = self['send'] = function (tagObject) {
var buffer = {
'p': _getFullName(tagObject),
's2': (tagObject['level2'] || '')
},
resultCheck = true;
//customObject: Si on passe un customObject alors qu'il y en a potentiellement un permanent dans le buffer, il faut les fusionner.
//Explication: Le builder envoie TOUJOURS les éléments permanents du moment qu'ils sont du bon type.
//Si il y a un stc permanent, il faut récupérer sa valeur et l'utiliser pour compléter le customObject (prioritaire) passé en paramètre.
//Si il n'y a pas de stc permanent dans le buffer, on envoie simplement le customObject passé en paramètre.
var customObjectValue = tagObject['customObject'];
if (customObjectValue) {
var bufferCustomObject = parent.getParam('stc', true);
if (bufferCustomObject && bufferCustomObject.options['permanent']) {
var tabTypeHit = bufferCustomObject ? bufferCustomObject.options['hitType'] : [];
var _arrayIndexOf = ATInternet.Utils.arrayIndexOf;
var isCorrectTypeHit = ((_arrayIndexOf(tabTypeHit, 'page') != -1) || (_arrayIndexOf(tabTypeHit, 'all') != -1));
if (isCorrectTypeHit) {
customObjectValue = ATInternet.Utils.completeFstLevelObj((bufferCustomObject.value || {}), customObjectValue, true);
}
}
parent['exec']('Utils', 'customObjectToString', [customObjectValue], function (data) {
buffer['stc'] = data;
});
}
//vrn management.
var contextPageObject = parent.getContext('page') || {};
if (contextPageObject.vrn) {
buffer['vrn'] = contextPageObject.vrn;
contextPageObject.vrn = undefined;
parent.setContext('page', contextPageObject);
}
// internalSearch management.
var contextInternalSearch = parent.getContext('InternalSearch') || {};
if(typeof contextInternalSearch.keyword != 'undefined'){
buffer['mc'] = ATInternet.Utils.cloneSimpleObject(contextInternalSearch.keyword);
if(typeof contextInternalSearch.resultPageNumber != 'undefined'){
buffer['np'] = ATInternet.Utils.cloneSimpleObject(contextInternalSearch.resultPageNumber);
}
parent.setContext('InternalSearch',undefined);
}
//Safari preview.
if (ATInternet.Utils.isPreview() && parent.getConfig('preview')) {
buffer['pvw'] = 1;
}
//Indicators.
_setIndicatorVariables(buffer, tagObject['customVars'], true);
//Dynamic label.
_setDynamicLabel(buffer, tagObject['dynamicLabel'], true);
//Tags.
_setTags(buffer, tagObject['tags'], true);
//Custom Tree Structure.
_setCustomTreeStructure(buffer, tagObject['customTreeStructure'], true);
//Campaigns variables.
var contextCampaignsObject = parent.getContext('campaigns') || {};
_setCampaignsVariables(buffer, contextCampaignsObject, true);
parent.setContext('campaigns', undefined);
parent['exec']('TechClicks', 'manageClick', [tagObject['elem'], tagObject['event'], tagObject['callback']], function (data) {
resultCheck = data;
});
_manageSend(function(){ parent.sendHit(buffer); });
contextPageObject.name = _magic(contextPageObject.name, tagObject['name'], '');
contextPageObject.level2 = _magic(contextPageObject.level2, tagObject['level2'], '');
//Create chapters keys with undefined value is not wanted here.
_setDeclaredProperty(contextPageObject, tagObject, 'chapter1');
_setDeclaredProperty(contextPageObject, tagObject, 'chapter2');
_setDeclaredProperty(contextPageObject, tagObject, 'chapter3');
parent.setContext('page', contextPageObject);
/* @if debug */
parent.debug('Page:page:send','DEBUG','method ended',tagObject);
/* @endif */
return resultCheck;
};
/**
* [Helper added by plugin {@link ATInternet.Tracker.Plugins.Page Page}] Will be called by tracker.dispatch if any page has been set.
* @alias page.onDispatch
* @memberof! ATInternet.Tracker.Tag#
* @function
* @private
*/
parent['page']['onDispatch'] = self['onDispatch'] = function () {
var contextPageObject = parent.getContext('page') || {};
var contextInternalSearch = parent.getContext('InternalSearch') || {};
parent.setParam('p', _getFullName(contextPageObject));
parent.setParam('s2', (contextPageObject['level2'] || ''));
//vrn management
if (contextPageObject.vrn) {
parent.setParam('vrn', contextPageObject.vrn);
contextPageObject.vrn = undefined;
parent.setContext('page', contextPageObject);
}
// internalSearch management
if(typeof contextInternalSearch.keyword != 'undefined'){
parent.setParam('mc', ATInternet.Utils.cloneSimpleObject(contextInternalSearch.keyword));
if(typeof contextInternalSearch.resultPageNumber != 'undefined'){
parent.setParam('np', ATInternet.Utils.cloneSimpleObject(contextInternalSearch.resultPageNumber));
}
parent.setContext('InternalSearch',undefined);
}
//Safari preview.
if (ATInternet.Utils.isPreview() && parent.getConfig('preview')) {
parent.setParam('pvw', 1);
}
//Indicators.
_setIndicatorVariables(null, contextPageObject['customVars'], false);
//Dynamic label.
_setDynamicLabel(null, contextPageObject['dynamicLabel'], false);
//Tags.
_setTags(null, contextPageObject['tags'], false);
//Custom Tree Structure.
_setCustomTreeStructure(null, contextPageObject['customTreeStructure'], false);
//Campaigns variables.
var contextCampaignsObject = parent.getContext('campaigns') || {};
_setCampaignsVariables(null, contextCampaignsObject, false);
parent.setContext('campaigns', undefined);
//customObject.
var contextCustomObject = contextPageObject['customObject'];
var pageOptions = [['hitType', ['page']]];
if (contextCustomObject) {
var bufferCustomObject = parent.getParam('stc', true);
if (bufferCustomObject) {
var tabTypeHit = bufferCustomObject.options['hitType'] || [];
var _arrayIndexOf = ATInternet.Utils.arrayIndexOf;
var isCorrectTypeHit = ((_arrayIndexOf(tabTypeHit, 'page') != -1) || (_arrayIndexOf(tabTypeHit, 'all') != -1));
var isPermanent = bufferCustomObject.options['permanent'];
if (isCorrectTypeHit) {
var clonedBufferCustomObject = ATInternet.Utils.cloneSimpleObject(bufferCustomObject);
clonedBufferCustomObject.value = ATInternet.Utils.completeFstLevelObj((clonedBufferCustomObject.value || {}), contextCustomObject, true);
parent.setParam('stc', clonedBufferCustomObject.value, {'encode': true});
_manageSend(function(){ parent.sendHit(null, pageOptions); });
if (isPermanent) {
parent.setParam('stc', bufferCustomObject.value, bufferCustomObject.options);
}
}
else {
parent.setParam('stc', contextCustomObject, {'encode': true});
_manageSend(function(){ parent.sendHit(null, pageOptions); });
parent.setParam('stc', bufferCustomObject.value, bufferCustomObject.options);
}
}
else {
parent.setParam('stc', contextCustomObject, {'encode': true});
_manageSend(function(){ parent.sendHit(null, pageOptions); });
}
}
else {
_manageSend(function(){ parent.sendHit(null, pageOptions); });
}
};
// For unit tests on private elements !!!
/* @if test */
self['_getFullName'] = _getFullName;
self['_magic'] = _magic;
self['_setDeclaredProperty'] = _setDeclaredProperty;
self['_manageSend'] = _manageSend;
self['_setIndicatorVariables'] = _setIndicatorVariables;
self['_setDynamicLabel'] = _setDynamicLabel;
self['_setTags'] = _setTags;
self['_setCustomTreeStructure'] = _setCustomTreeStructure;
self['_setCampaignsVariables'] = _setCampaignsVariables;
/* @endif */
};
window['ATInternet']['Tracker']['addPlugin']('Page');