Source: Page/page.js

/**
 * @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');