Source: OnSiteAds/onsiteads.js

/**
 * @class
 * @classdesc Plugin used to manage publisher and self-promotion.
 * @name OnSiteAds
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param tag {object} Instance of the Tag used
 * @public
 */
ATInternet.Tracker.Plugins.OnSiteAds = function (tag) {

    'use strict';

    var self = this;

    // Plugin's dependencies
    var _dependencies = ['Utils', 'TechClicks'];
    // Current url
    var _href = '';
    var _debug = {
        level: 'DEBUG',
        messageEnd: 'method ended',
        messageStart: 'method start'
    };

    /**
     * Get page label with chapters
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} page context
     * @return string {string} Page name completed with chapters (all from page context)
     * @private
     */
    var _getFullName = function (tagObject) {
        return tag.utils.manageChapters(tagObject, 'chapter', 3) + (tagObject['name'] ? tagObject['name'] : '');
    };

    /**
     * Get a property in an object
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param object {object} object to use
     * @param key {string} key wanted
     * @return string {*} Either the value otherwise an empty string
     * @private
     */
    var _getProperty = function (object, key) {
        return (object && object[key] ? object[key] : '');
    };

    /**
     * Build a Publisher or Self-Promotion campaign (based on tag data)
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} tag object
     * @param clickOrImpression {string} key indicating which object is to process (either a "click" or an "impression")
     * @return string {string} Campaign formatted depending on tag data
     * @private
     */
    var _buildCampaign = function (tagObject, clickOrImpression) {
        var campaign = _getProperty(tagObject, clickOrImpression);
        if (campaign) {
            var prefix = _getProperty(tagObject, 'prefix');
            if (campaign.campaignId) { // publisher
                prefix = prefix || 'PUB';
                var campaignId = _getProperty(campaign, 'campaignId'),
                    creation = _getProperty(campaign, 'creation'),
                    variant = _getProperty(campaign, 'variant'),
                    formatPublisher = _getProperty(campaign, 'format'),
                    generalPlacement = _getProperty(campaign, 'generalPlacement'),
                    detailedPlacement = _getProperty(campaign, 'detailedPlacement'),
                    advertiserId = _getProperty(campaign, 'advertiserId'),
                    url = _getProperty(campaign, 'url');
                return prefix + '-' + campaignId + '-' + creation + '-' + variant + '-' + formatPublisher + '-' + generalPlacement + '-' + detailedPlacement + '-' + advertiserId + '-' + url;
            } else if (campaign.adId) { // selfpromotion
                prefix = prefix || 'INT';
                var adId = _getProperty(campaign, 'adId'),
                    formatSelfPromotion = _getProperty(campaign, 'format'),
                    productId = _getProperty(campaign, 'productId');
                return prefix + '-' + adId + '-' + formatSelfPromotion + '||' + productId;
            }
        }
        return '';
    };

    /**
     * Send an individual campaign's click hit (hiType is "onSiteAdsClick")
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} tag object
     * @param elementType {string} Element type (mailto, form, redirection)
     * @private
     */
    var _sendClick = function (tagObject, elementType) {

        tagObject = tagObject || {};

        var hitType = ['onSiteAdsClick'];
        var contextPageObject = tag.getContext('page') || {};
        var buffer = {};
        buffer.atc = {
            _value: _buildCampaign(tagObject, 'click'),
            _options: {
                truncate: true
            }
        };
        buffer.type = 'AT';
        buffer.patc = _getFullName(contextPageObject);
        buffer.s2atc = contextPageObject.level2 || '';
        var customObjectValue = tagObject.customObject;
        if (customObjectValue) {
            var hitParam = 'stc';
            customObjectValue = tag.processTagObject(hitParam, hitType, customObjectValue);
            buffer[hitParam] = {
                _value: ATInternet.Utils.jsonSerialize(customObjectValue),
                _options: {
                    hitType: hitType,
                    encode: true,
                    separator: ',',
                    truncate: true
                }
            };
        }
        tag.sendHit(buffer, [['hitType', hitType]], tagObject.callback, null, elementType);
    };

    /**
     * Send an individual campaign's impression hit (hiType is "onSiteAdsImpression")
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} tag object
     * @param elementType {string} Element type (mailto, form, redirection)
     * @private
     */
    var _sendImpression = function (tagObject, elementType) {

        tagObject = tagObject || {};

        var hitType = ['onSiteAdsImpression'];
        var buffer = {};
        buffer.ati = {
            _value: _buildCampaign(tagObject, 'impression'),
            _options: {
                hitType: hitType,
                truncate: true
            }
        };
        buffer.type = 'AT';
        //Safari preview.
        if (ATInternet.Utils.isPreview() && tag.getConfig('preview')) {
            buffer.pvw = 1;
        }
        var customObjectValue = tagObject.customObject;
        if (customObjectValue) {
            var hitParam = 'stc';
            customObjectValue = tag.processTagObject(hitParam, hitType, customObjectValue);
            buffer[hitParam] = {
                _value: ATInternet.Utils.jsonSerialize(customObjectValue),
                _options: {
                    hitType: hitType,
                    encode: true,
                    separator: ',',
                    truncate: true
                }
            };
        }
        tag.manageSend(function () {
            tag.sendHit(buffer, [['hitType', hitType]], tagObject.callback, null, elementType);
        });
    };

    /**
     * Push a new impression's campaign to be sent at dispatch
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param campaignValue {object} campaign
     * @param hitType {object} Either "selfPromotion" or "publisher"
     * @private
     */
    var _pushImpression = function (campaignValue, hitType) {
        var ati = tag.buffer.get('ati', true) || {};
        if (typeof ati._value === 'string') {
            ati._value = [ati._value];
        } else {
            ati._value = ati._value || [];
        }
        ati._options = ati._options || {truncate: true, hitType: [hitType, 'page']};
        ati._value.push(campaignValue);
        tag.buffer.set('ati', ati._value, ati._options);
    };

    /**
     * Set a campaign for a futur dispatch
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} tag object
     * @param hitType {object} Either "selfPromotion" or "publisher"
     * @private
     */
    var _simpleSet = function (tagObject, hitType) {

        tagObject = tagObject || {};

        if (tagObject.click) {
            tag.setParam('atc', _buildCampaign(tagObject, 'click'), {truncate: true, hitType: [hitType, 'page']});
        } else if (tagObject.impression) {
            tag.setParam('ati', _buildCampaign(tagObject, 'impression'), {
                truncate: true,
                hitType: [hitType, 'page']
            });
        }

        if (tagObject.customObject) {
            tag.setContext('onsiteads', {customObject: tagObject.customObject});
            var contextPageObject = tag.getContext('page') || {};
            contextPageObject.customObject = ATInternet.Utils.completeFstLevelObj(contextPageObject.customObject, tagObject.customObject, false);
            tag.setContext('page', contextPageObject);
        }

        tag.dispatchSubscribe('onSiteAds');
    };

    //Définition des helpers
    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tags for self-promotion campaigns
     * @name selfPromotion
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#selfPromotion.set}
     * @property {function} add Tag helper, see details here {@link ATInternet.Tracker.Tag#selfPromotion.add}
     * @property {function} send Tag helper, see details here {@link ATInternet.Tracker.Tag#selfPromotion.send}
     * @public
     */
    tag.selfPromotion = {};

    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tags for publisher campaigns
     * @name publisher
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#publisher.set}
     * @property {function} add Tag helper, see details here {@link ATInternet.Tracker.Tag#publisher.add}
     * @property {function} send Tag helper, see details here {@link ATInternet.Tracker.Tag#publisher.send}
     * @public
     */
    tag.publisher = {};

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tagging method for publisher campaigns, to be used with the tag.dispatch() method
     * @alias publisher.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} tagObject must contain a property 'click' or 'impression', you can force a specific prefix with a property 'prefix'
     * @example
     * <pre><code class="javascript">tag.publisher.set({
     *      impression:{
     *          campaignId : 'id[label]',
     *          creation : 'id[label]',
     *          variant : 'id[label]',
     *          format : '[120x40]',
     *          generalPlacement : '[label]',
     *          detailedPlacement : 'id[label]',
     *          advertiserId : 'id[label]',
     *          url : '[urlEncoded]'
     *      }
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &atc=PUB-id[campaignId]-id[creation]-id[variant]-id-[generalPlacement]-[detailedPlacement]-id[advertiserId]-urlencoded
     * @public
     */
    tag.publisher.set = function (tagObject) {
        _simpleSet(tagObject, 'publisher');
        /* @if debug */
        tag.debug('OnSiteAds:publisher:set', _debug.level, _debug.messageEnd, tagObject);
        /* @endif */
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tagging method for self-promotion campaigns, to be used with the tag.dispatch() method
     * @alias selfPromotion.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} tagObject must contain a property 'click' or 'impression', you can force a specific prefix with a property 'prefix'
     * @example
     * <pre><code class="javascript">tag.selfPromotion.set({
     *     impression : {
     *         adId : 'integer',
     *         format : 'id[format]',
     *         productId : 'productId'
     *     }
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &ati=INT-integer-id[format]||productId
     * <pre><code class="javascript">tag.selfPromotion.set({
     *     click : {
     *         adId : 'integer',
     *         format : 'id[format]',
     *         productId : 'productId'
     *     }
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &atc=INT-integer-id[format]||productId
     * <pre><code class="javascript">tag.selfPromotion.set({
     *     click : {
     *         adId : 'integer',
     *         format : 'id[format]',
     *         productId : 'productId'
     *     },
     *     prefix : 'VALUE',
     *     customObject:{one:1,two:2}
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &atc=VALUE-integer-id[format]||productId
     * @public
     */
    tag.selfPromotion.set = function (tagObject) {
        _simpleSet(tagObject, 'selfPromotion');
        /* @if debug */
        tag.debug('OnSiteAds:selfPromotion:set', _debug.level, _debug.messageEnd, tagObject);
        /* @endif */
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tagging method for publisher campaigns, allow to cumulate campaigns to be sent with the tag.dispatch() method
     * @alias publisher.add
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} tagObject must contain a property 'click' or 'impression', you can force a specific prefix with a property 'prefix'
     * @example
     * <pre><code class="javascript">tag.publisher.add({
     *      impression:{
     *          campaignId : 'id[label]',
     *          creation : 'id[label]',
     *          variant : 'id[label]',
     *          format : '[120x40]',
     *          generalPlacement : '[label]',
     *          detailedPlacement : 'id[label]',
     *          advertiserId : 'id[label]',
     *          url : '[urlEncoded]'
     *      }
     * });
     * tag.publisher.add({
     *      impression:{
     *          campaignId : 'id2[label2]',
     *          creation : 'id2[label2]',
     *          variant : 'id2[label2]',
     *          format : '[60x40]',
     *          generalPlacement : '[label2]',
     *          detailedPlacement : 'id2[label2]',
     *          advertiserId : 'id2[label2]',
     *          url : '[urlEncoded2]'
     *      }
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &atc=PUB-id[campaignId]-id[creation]-id[variant]-id-[generalPlacement]-[detailedPlacement]-id[advertiserId]-urlencoded
     * @public
     */
    tag.publisher.add = function (tagObject) {
        _pushImpression(_buildCampaign(tagObject, 'impression'), 'publisher');
        tag.dispatchSubscribe('onSiteAds');
        /* @if debug */
        tag.debug('OnSiteAds:publisher:add', _debug.level, _debug.messageEnd, tagObject);
        /* @endif */

    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tagging method for self-promotion campaigns, allow to cumulate campaigns to be sent with the tag.dispatch() method
     * @alias selfPromotion.add
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} tagObject must contain a property 'click' or 'impression', you can force a specific prefix with a property 'prefix'
     * @example
     * <pre><code class="javascript">tag.selfPromotion.add({
     *     impression : {
     *         adId : 'integer',
     *         format : 'id[format]',
     *         productId : 'productId'
     *     }
     * });
     * tag.selfPromotion.add({
     *     impression : {
     *         adId : 'integer2',
     *         format : 'id2[format2]',
     *         productId : 'productId2'
     *     }
     * });
     * tag.dispatch();
     * </code></pre>
     * This will send a self-promotion campaign like : &ati=INT-integer-id[format]||productId,INT-integer2-id2[format2]||productId2
     * @public
     */
    tag.selfPromotion.add = function (tagObject) {
        _pushImpression(_buildCampaign(tagObject, 'impression'), 'selfPromotion');
        tag.dispatchSubscribe('onSiteAds');
        /* @if debug */
        tag.debug('OnSiteAds:selfPromotion:add', _debug.level, _debug.messageEnd, tagObject);
        /* @endif */
    };

    /**
     * Generic method to send self-promotion or publisher campaigns.
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @param tagObject {object} tagObject should contain the campaign object, optionally a "customObject" and a "elem"(HTMLElement, to manage redirections)
     * @private
     */
    self.advertEvent = function (tagObject) {

        tagObject = tagObject || {};

        var preservePropagation = true;
        var elementType = '';
        var eventObject = null;
        if (tagObject.hasOwnProperty('event')) {
            eventObject = tagObject.event || window.event;
        }
        if (!ATInternet.Utils.isTabOpeningAction(eventObject) && tagObject.elem) {
            var manage = tag.techClicks.manageClick(tagObject.elem, eventObject);
            preservePropagation = manage.preservePropagation;
            elementType = manage.elementType;
        }
        if (tagObject.click) {
            _sendClick(tagObject, elementType);
        } else if (tagObject.impression) {
            _sendImpression(tagObject, elementType);
        }
        return preservePropagation;
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Alternative tagging method for publisher campaigns. This method manages redirections on click if necessary
     * @alias publisher.send
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} The campaign , you can add a "customObject" property, and an "elem" property to manage redirection
     * @example
     * <pre><code class="html">&lt;a href="..." onclick="return tag.publisher.send({elem:this,click:{campaignId:'id[label]',creation:'id[label]',variant:'id[label]',format:'[120x40]',generalPlacement:'[label]',detailedPlacement:'id[label]',advertiserId:'id[label]',url:'[urlEncoded]'}});"&gt;Pub&lt;/a&gt;
     * </code></pre>
     * @public
     */
    tag.publisher.send = function (tagObject) {
        /* @if debug */
        tag.debug('OnSiteAds:publisher:send', _debug.level, _debug.messageStart, tagObject);
        /* @endif */
        return self.advertEvent(tagObject);
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Alternative tagging method for self-promotion campaigns. This method manages redirections on click if necessary
     * @alias selfPromotion.send
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} The campaign , you can add a "customObject" property, and an "elem" property to manage redirection
     * @example
     * <pre><code class="html">&lt;a href="..." onclick="return tag.selfPromotion.send({elem:this,click:{adId:'id',format:'[120x40]',productId:'id'}});"&gt;Pub&lt;/a&gt;
     * </code></pre>
     * @public
     */
    tag.selfPromotion.send = function (tagObject) {
        /* @if debug */
        tag.debug('OnSiteAds:selfPromotion:send', _debug.level, _debug.messageStart, tagObject);
        /* @endif */
        return self.advertEvent(tagObject);
    };

    //'OnSitesAds' est le helper commun aux quatre définis avant.
    //Il permet de définir une seule méthode 'send' pour les quatre.
    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Tags for campaigns
     * @name onSiteAds
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @private
     */
    tag.onSiteAds = {};

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.OnSiteAds OnSiteAds}] Will be called by tracker.dispatch if any self-promotion/publisher set/add has been called
     * @alias onSiteAds.onDispatch
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param callback {function} Callback to execute
     * @param elementType {string} Element type (mailto, form, redirection)
     * @private
     */
    tag.onSiteAds.onDispatch = function (callback, elementType) {
        if (!tag.dispatchSubscribed('page')) {

            tag.setParam('type', 'AT', {hitType: ['publisher', 'selfPromotion']});

            var contextPageObject = tag['getContext']('page') || {};
            if (tag.getParam('atc')) {
                tag.setParam('patc', _getFullName(contextPageObject), {hitType: ['publisher', 'selfPromotion']});
                tag.setParam('s2atc', contextPageObject['level2'] || '', {hitType: ['publisher', 'selfPromotion']});
            }

            //Safari preview.
            if (ATInternet.Utils.isPreview() && tag.getConfig('preview')) {
                tag.setParam('pvw', 1);
            }

            var hitType = ['publisher', 'selfPromotion'];
            var contextOnSiteAds = tag.getContext('onsiteads') || {};
            var contextObject = contextOnSiteAds.customObject;
            if (contextObject) {
                var hitParam = 'stc';
                var paramOptions = {
                    'hitType': hitType,
                    'encode': true,
                    'separator': ',',
                    'truncate': true,
                    'elementType': elementType
                };
                tag.processContextObjectAndSendHit(hitParam, paramOptions, contextObject, callback);
            } else {
                tag.manageSend(function () {
                    tag.sendHit(null, [['hitType', hitType]], callback, null, elementType);
                });
            }
        }
    };

    /**
     * Run process.
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @private
     */
    var _run = function () {
        _href = document.location.href;
        var data = tag.utils.getQueryStringValue('xtatc', _href);
        if (data) {
            tag.setParam('atc', data, {hitType: ['publisher', 'selfPromotion', 'page']});
        }
        tag.emit('OnSiteAds:Ready', {
            lvl: 'INFO',
            details: {
                href: _href
            }
        });
    };

    /**
     * Initialize plugin.
     * @memberof ATInternet.Tracker.Plugins.OnSiteAds#
     * @function
     * @private
     */
    var _init = function () {
        tag.plugins.waitForDependencies(_dependencies, _run);
    };

    _init();

    /* @if test */
    self._sendClick = _sendClick;
    self._sendImpression = _sendImpression;
    /* @endif */
};
ATInternet.Tracker.addPlugin('OnSiteAds');