Source: Weborama/weborama.js

/**
 * @class
 * @classdesc Plugin to collect marketing data from Weborama Partner.
 * @name Weborama
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param tag {object} Instance of the Tag used
 * @public
 */
ATInternet.Tracker.Plugins.Weborama = function (tag) {

    'use strict';

    var _this = this;
    var _config = {};
    var _customWeboObject = {};
    var _set_storage_method = '';
    var _get_storage_method = '';
    var _storageVisitValue = null;
    var _timeout = false;
    var _done = false;
    var _debug = {
        level: 'DEBUG',
        messageEnd: 'method ended'
    };

    /**
     * Init Weborama configuration.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _initConfig = function () {
        // Set visitLifetime value from global configuration.
        tag.setConfig('visitLifetime', dfltGlobalCfg.visitLifetime, true);
        // Set specific plugin configuration.
        // If global configuration already exists, set only undefined properties.
        tag.configPlugin('Weborama', dfltPluginCfg || {});
        // The last instance of tracker which set a weborama will be the one called by weborama API
        var uuid = ATInternet.Utils.uuid();
        var id = parseInt(uuid.num(8));
        tag.configPlugin('Weborama', {id: id}, function (newConf) {
            _config = newConf;
        });
        window.ATInternet.Weborama.tagInstances.push(tag);
        _config.callback = '(function(weboObject){window.ATInternet.Weborama.callback(weboObject,' + id + ')})';
        _config.url = ((document.location.protocol === 'https:') ? 'https://' : 'http://') + _config.baseUrl;
    };

    /**
     * Init Weborama info object.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _initInfoWebo = function () {
        // Create final Weborama object
        _customWeboObject.info = {
            version: _config.version,
            accountid: _config.accountId,
            message: '',
            errors: []
        };
    };

    /**
     * Define labels to use for unique persistence.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _defineUniquePersistence = function () {
        _set_storage_method = 'set' + (_config.domainAttribution ? '' : 'Private');
        _get_storage_method = 'get' + (_config.domainAttribution ? '' : 'Private');
    };

    /**
     * Helper to use the plugin Storage.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @param method {string} Method to call in the plugin
     * @param params {Array} Parameters to transmit
     * @returns {*}
     * @private
     */
    var _pluginStorage = function (method, params) {
        var ret = null;
        tag.plugins.exec('Storage', method, params, function (data) {
            ret = data;
        });
        return ret;
    };

    /**
     * Get persistent and direct spot values from stored data.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _getStorageValues = function () {
        _storageVisitValue = _pluginStorage(_get_storage_method, ['atwebosession']);
    };

    /**
     * Set Weborama script error.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _setScriptError = function () {
        _customWeboObject.info.errors.push('noScript');
    };

    /**
     * Check if a stored data is present and with type object, if not it creates it and returns true,
     * if present but with another type it returns false.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @param name {string} Name of the stored data you need to check
     * @param options {object} Options of the data to create
     * @return {boolean}
     * @private
     */
    var _checkStorage = function (name, options) {
        var temp = _pluginStorage(_get_storage_method, [name]);
        if (temp !== null) {
            return (typeof temp === 'object' && !(temp instanceof Array));
        } else {
            _pluginStorage(_set_storage_method, [name, {}, options]);
            return true;
        }
    };

    /**
     * Set Weborama data.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _setDataWebo = function () {
        // Set session storage for the visit.
        var options = {
            path: _config.path,
            session: tag.getConfig('visitLifetime') * 60
        };
        if (_checkStorage('atwebosession', options)) {
            if (_storageVisitValue === null) {
                _pluginStorage(_set_storage_method, ['atwebosession', _customWeboObject, options]);
            }
        }
        // Update session storage on trigger 'Tracker:Hit:Sent:Ok'.
        tag.onTrigger('Tracker:Hit:Sent:Ok', function () {
            _pluginStorage(_get_storage_method, ['atwebosession']);
        });

        // Add storage error message if atwebosession is null.
        if (_pluginStorage(_get_storage_method, ['atwebosession', true]) === null) {
            _customWeboObject.info.errors.push('storageError');
        }
    };

    /**
     * Set Page context.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _setPageContext = function () {
        var contextPageObject = tag.getContext('page') || {};
        var contextCustomObject = contextPageObject['customObject'] || {};
        contextCustomObject.weborama = _customWeboObject;
        contextPageObject.customObject = contextCustomObject;
        // Set new custom object in page context
        tag.setContext('page', contextPageObject);
        tag.processSpecificDispatchEventFor('weborama');
        _done = true;
    };

    /**
     * Set Weborama timeout error.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _setTimeoutError = function () {
        _customWeboObject.info.errors.push('timeout');
        _timeout = true;
    };

    /**
     * Run Weborama global processing.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _run = function () {
        tag.addSpecificDispatchEventFor('weborama');
        var callback = function (error) {
            if (!_timeout) {
                if (error !== null) {
                    _setScriptError();
                }
                _setDataWebo();
                _setPageContext();
            }
        };
        ATInternet.Utils.loadScript({url: _config.url + '&a.si=' + _config.accountId + '&a.cb=' + _config.callback + '&rn=' + Math.random()}, callback);
        var errorTimeout = function () {
            if (!_done) {
                _setTimeoutError();
                _setDataWebo();
                _setPageContext();
            }
        };
        setTimeout(errorTimeout, 500);
    };

    /**
     * Process Weborama stored visit.
     * @memberof ATInternet.Tracker.Plugins.Weborama#
     * @function
     * @private
     */
    var _processStorageVisitValue = function () {
        var index = ATInternet.Utils.arrayIndexOf(_storageVisitValue.info.errors, 'timeout');
        if (_storageVisitValue.info.message.length > 0 && index !== -1) {
            _storageVisitValue.info.errors.splice(index, 1);
            _customWeboObject.info = _storageVisitValue.info;
            _storageVisitValue = null;
        } else {
            _customWeboObject.info.message = 'sessionAlreadyActive';
        }
    };

    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.Weborama Weborama}] Tags to collect marketing data from Weborama Partner.
     * @name weborama
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#weborama.set}
     * @property {function} callback Tag helper, see details here {@link ATInternet.Tracker.Tag#weborama.callback}
     * @public
     */
    tag.weborama = {};

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Weborama Weborama}] Set Weborama parameters.
     * @alias weborama.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @example
     * <pre><code class="javascript">tag.weborama.set();
     * </code></pre>
     * @public
     */
    tag.weborama.set = function () {

        // Register helper to final call in order to send messages.
        tag.dispatchSubscribe('weborama');
        _initConfig();
        _initInfoWebo();
        /* @if test */
        var acceptStorage = false;
        /* @endif */
        if (!tag.getConfig('disableCookie') && !tag.getConfig('disableStorage')) {
            /* @if test */
            acceptStorage = true;
            /* @endif */
            _defineUniquePersistence();
            _getStorageValues();
            if (!_storageVisitValue) {
                if (_config.baseUrl && typeof _config.baseUrl === 'string') {
                    _run();
                } else {
                    _customWeboObject.info.message = 'noURLSet';
                    _setDataWebo();
                    _setPageContext();
                }
            } else {
                _processStorageVisitValue();
                _setDataWebo();
                _setPageContext();
            }
        } else {
            _customWeboObject.info.message = 'disableStorage:true';
            _setPageContext();
        }
        /* @if debug */
        tag.debug('Weborama:weborama:set', _debug.level, _debug.messageEnd, _customWeboObject);
        /* @endif */
        /* @if test */
        return acceptStorage;
        /* @endif */
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Weborama Weborama}] Callback (called by Partner).
     * @alias weborama.callback
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @example
     * <pre>code class="javascript">tag.weborama.callback();
     * </code></pre>
     * @public
     */
    tag.weborama.callback = function (response) {
        if (typeof response !== 'undefined') {
            if (response.last_action) {
                _customWeboObject.info.message = response.last_action;
            } else {
                _customWeboObject.info.message = 'noAction';
            }
            if (response.webo_cid) {
                _customWeboObject.info.userid = response.webo_cid;
            }
        } else {
            _customWeboObject.info.errors.push('noData');
        }
        if (_timeout) {
            _storageVisitValue = null;
            _setDataWebo();
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Weborama Weborama}] Will be called by tracker.dispatch if any Weborama has been set.
     * @alias weborama.onDispatch
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param callback {function} Callback to execute
     * @private
     */
    tag.weborama.onDispatch = function (callback) {
        callback && callback();
        if (!tag.dispatchSubscribed('page')) {
            /* @if debug */
            tag.debug('Weborama:weborama:onDispatch:Error', 'WARNING', 'Weborama data are not sent without page information (use page.set())');
            /* @endif */
        }
    };

    // For unit tests on private elements !!!
    /* @if test */
    _this._initConfig = _initConfig;
    _this._initInfoWebo = _initInfoWebo;
    _this._defineUniquePersistence = _defineUniquePersistence;
    _this._getStorageValues = _getStorageValues;
    _this._pluginStorage = _pluginStorage;
    _this._run = _run;
    _this._setScriptError = _setScriptError;
    _this._setDataWebo = _setDataWebo;
    _this._checkStorage = _checkStorage;
    _this._setPageContext = _setPageContext;
    _this._setTimeoutError = _setTimeoutError;
    _this._getStorageMethods = function () {
        _this._set_storage_method = _set_storage_method;
        _this._get_storage_method = _get_storage_method;
    };
    /* @endif */
};
window.ATInternet.Weborama = {
    tagInstances: [],
    callback: function (response, id) {
        var tagInstances = window.ATInternet.Weborama.tagInstances;
        for (var i = 0; i < tagInstances.length; i++) {
            if (tagInstances[i].getConfig('Weborama').id === id) {
                tagInstances[i]['weborama']['callback'](response);
            }
        }
    }
};
ATInternet.Tracker.addPlugin('Weborama');