jester.js

From disqus.com, 1 Month ago, written in JavaScript, viewed 3 times. This paste is a reply to identity.js from disqus.com - go back
URL https://pastebin.freepbx.org/view/4b98d8a2/diff Embed
Viewing differences between identity.js and jester.js
define('core/analytics/identity',[
    'exports',

    'core/utils/cookies',
    'core/utils/guid',
    'core/utils/hash',
    'core/utils/fingerprint',
define('core/analytics/jester',[
    'jquery',
    'underscore',
    'backbone',

    'core/analytics/identity',
    'core/config/urls',
], function (
    exports,

    cookies,
    guid,
    hash,
    fingerprint
$,
    _,
    Backbone,

    identity,
    urls
) {
    'use strict';

    var initialized = false;

    var ImpressionManager = exports.ImpressionManager = function () {
        // Will be updated by calls made from individual app initializations. Defaults to true to be safe
        this.isPrivate = true;

        this.impId = guid.generate();
    };
    ImpressionManager.prototype.COOKIE_NAME = '__jid';  // jid 
/*
        Jester 
is 'jester impression id'
    ImpressionManager.prototype.TTL = 30 * 60 * 1000;  // TTL 
an ActivityStreams logger for Disqus.

        # About Product, Zone, Section, Area:

        Yeah, you are probably confused about what these descriptors mean. We are mostly confused, too.
        So, to help out, here is a comprehensive guide:

            Product
                A product is a suite of one or many applications that fall underneath an analytics
                'umbrella'. These are currently only 'embed' and 'home'.

            Zone
                A zone represents 
the impression cookie product application that the user is 30 minutes
    ImpressionManager.prototype.init = function (options) {
        // This function should be called upon app initialization, before this manager's values
        // or functions 
currently interacting with.
                These 
are utilized

        this.isPrivate = options && options.isPrivate;

        if (!this.isPrivate)
            this.prevImp = cookies.read(this.COOKIE_NAME);

        this.persist();
    };
    ImpressionManager.prototype.setImpressionId = function (impId) {
        this.impId = impId;
        this.persist();
    };
    ImpressionManager.prototype.persist = function () {
        // TODO: 
currently 'thread', 'notifications', 'profile', 'onboard', and 'community'.

            Section
                Section is the "route" that the application is currently displaying. 
This is getting wiped if we find out `isPrivate` is actually
        // false later since it is initialized before 
analogous
                to a Backbone.Router method. It must uniquely represent 
the session is fetched
        // 
*visual state* of the application
                at the time of the interaction we are logging. Applications may have only one route, or
                they may have many routes.

            Area
                An xpath-ish type identifier that describes where in the DOM the logged interaction took place,
                if any. Some interactions may not have a DOM location, in 
which can influence `isPrivate`.
        if (this.isPrivate) 
case 'n/a' is sent instead.
                Actual Xpath not really required.

        # Serializing Product, Zone, Section, Area:

        When we serialize Product, Zone, Section, or Area as an ActivitySteam object, we use a specific format
        that allows for proper analytics rollups both between products and between cross product applications:

        Products:
            object_type='product'
            object_id=<product name>

        Zones:
            object_type='zone'
            object_id=<zone name>

        Sections:
            object_type='section'
            object_id=<zone name>/<section name>

        Areas:
            object_type='area'
            object_id=<zone name>/<section name>#<area name>
    */

    var ActivityClient = Backbone.Model.extend({
        url: urls.jester + '/event.js',

        defaults: 
{
            cookies.erase(this.COOKIE_NAME);
            return;
        }

        // Set cookie so the current impression id
        // can be grabbed as the previous impression id in the next invocation.
        // (Expires after 30 minutes of inactivity.)
        cookies.create(this.COOKIE_NAME, this.impId, { expiresIn: this.TTL });
    };


    var UniqueManager = exports.UniqueManager = 
experiment: 'default',
            variant: 'control',
        },

        setHostReferrer: 
function () {
        // Will be updated by calls made from individual app initializations. Defaults to true to be safe
        this.isPrivate = true;
    };
    UniqueManager.prototype.COOKIE_NAME = 'disqus_unique';
    UniqueManager.prototype.TTL = 365 * 24 * 60 * 60 * 1000;  /* one year in ms */
    UniqueManager.prototype.init = function (options) {
        // This function should be called upon app initialization, before this manager's values
        // or functions are utilized
        this.isPrivate = options && options.isPrivate;

        
(url) {

            
if (this.isPrivate) {
            cookies.erase(this.COOKIE_NAME, 
(!url) {
                domain: // Indicate no referrer as direct traffic
                this.set('page_referrer', 'direct');
            } else if (url.indexOf('http') === -1) {
                // We should only set fully qualified URLs as
                // the referrer domain.
            } else {
                // If this the client visited cnn.com from facebook.com/xxxx,
                // and cnn.com loaded this embed, the page_referrer would
                // be facebook.com/xxxx.
                this.set('page_referrer', url);
            }
        },

        decoratePayload: function (payload) {

            // The default category for all our events
            // is 'activity'. Only allow overrides of this
            // during an `emit` call.
            if (!payload.event)
                payload.event = 'activity';

            // Allow payload attributes to override attributes
            // set on the client instance.
            payload = _.extend(this.toJSON(), payload);

            _.extend(payload, {
                imp: identity.impression.impId,
                prev_imp: identity.impression.prevImp,
            });

            // If there is no current application route for this event,
            // we assume it is the 'default' route of the application.
            if (!payload.section)
                payload.section = 'default';

            // If there is no specified event xpath (maybe this event did not
            // originate in the DOM), then we pass Not Available.
            if (!payload.area)
                payload.area = 'n/a';

            // IE8 and IE9 has a stupid limit on the URL length and we cannot
            // use POST method with Jester yet due to CORS issues (again in IE8
            // and IE9) so we simply check total length of the QSA part as
            // mentioned in MS KB article http://support.microsoft.com/kb/q208427
            // and if it is longer than the limit, 2048 chars, we replace it
            // with a more modest, page_referrer_domain
            //
            // NOTE: The final URL is still NOT guaranteed to be < 2048 chars
            var qsaLength = $.param(payload).length;
            if (qsaLength > 2048 && this.has('page_referrer')) {
                var referrerLink = 
window.location.host.split(':')[0],
document.createElement('a');
                referrerLink.href = this.get('page_referrer');
                var hostname = referrerLink.hostname;

                if (hostname)
                    payload.page_referrer_domain = hostname;

                delete payload.page_referrer;
            }

            return payload;
        },

        emit: function (payload) {
            // Fire the event to the jester endpoint and return
            // the deferred object
            return $.ajax({
                url: _.result(this, 'url'),
                data: this.decoratePayload(payload),
                dataType: 'script',

                // default is false for 'script' dataType, setting to true
                // so that "_={timestamp}" isn't appended to this request
                cache: true,
            });
            return;\r\n        }\r\n\r\n        // TODO: We are currently generating a new GUID each time we ever\r\n        // initialize with `isPrivate` which is the default behavior.  We\r\n        // could persist the GUID in localStorage so we can use it whenever\r\n        // we have consent and still keep deleting our cookie, or we can\r\n        // decide we don't need to delete our cookie anymore, but we will\r\n        // need to get legal's approval on which approach we are comfortable\r\n        // with.  A version of the latter (storing in localStorage) can be\r\n        // found in an early version of D28850.\r\n        this.value = cookies.read(this.COOKIE_NAME) || guid.generate();\r\n\r\n        // This needs to be called each time because if we ever\r\n        // change the options, existing cookies will not get updated.\r\n        cookies.create(this.COOKIE_NAME, this.value, {\r\n            domain: window.location.host.split(':')[0],\r\n            expiresIn: this.TTL,\r\n        });\r\n    };\r\n    UniqueManager.prototype.isPersistent         },
    });

    var logStat 
= function () logStat(name) {
        // If we were not able to set and read a cookie
        // then the browser does not support cookies.
        
var beacon = new window.Image();
        beacon.src = urls.jester + '/stat.gif?' + $.param({ event: name });

        
return !this.isPrivate && cookies.read(this.COOKIE_NAME) === this.value;
beacon;
    };

    exports.init var telemetry = function (options, force) telemetry(endpoint, payload) {
        if (initialized && !force)
            return;

        exports.impression.init(options);
        exports.unique.init(options);
        initialized 
(_.any(payload, function (val) { return val < 0; }))
            return;  // discard the whole data set if anything looks wrong

        // Round all values since statsd expects integers
        _.each(payload, function (val, key) { payload[key] 
true;
Math.round(val); });

        var beacon = new window.Image();
        beacon.src = urls.jester + '/telemetry/' + endpoint + '.gif?' + $.param(payload);

        return beacon;
    };

    exports.reset var client function () new ActivityClient();

    client.setHostReferrer(window.document.referrer);

    return 
{
        initialized = false;

        exports.impression = new ImpressionManager();
        exports.unique = new UniqueManager();
    };

    exports.reset();

    /**
     * Returns a consistent ID for this client.
     *
     * Uses either the disqus_unique cookie value or the
     * browser's fingerprint value if cookies are not supported.
     * @returns {string} client id
     */
    exports.clientId = function () {
        var manager = exports.unique;
        var value;

        if (manager.isPersistent())
            value = manager.value;

        return value || fingerprint.get().toString();
    };

    /**
     * Returns a number between 0..99 for a given string identifier.
     *
     * This method of determining a percent using a specific string identifier
     * (such as a forum shortname, username, disqus_unique id, etc.)
     *
     * https://blog.disqus.com/the-paper-plane-proof-our-uplifting-story-of-client-side-javascript-bucketing
     *
     * @param {string} str - String to get calculated into a percent bucket
     * @param {number} precision - Determines the percentage precision
     * @returns {number} Number that is calculated from the hashed input
     */
    exports.getPercentBucketForString = function (str, precision) {
        var max = 100;
        var stringHash = Math.abs(hash.calculate(str));
        if (precision) {
            var divisor = Math.pow(10, precision);
            return (stringHash % (max * divisor)) / divisor;
        }
        return stringHash % max;
    };

    /**
     * Calculates the percentile for the client ID.
     *
     * @returns {number} percentile - Number that is calculated from the hashed input
     */

    exports.clientPercent = function () {
        return exports.getPercentBucketForString(exports.clientId());
ActivityClient: ActivityClient,
        client: client,
        logStat: logStat,
        telemetry: telemetry,
    };
});

// https://c.disquscdn.com/next/next-core/core/analytics/identity.com/next/next-core/core/analytics/jester.js

Replies to jester.js rss

Title Name Language When
Re: reporting.js disqus.com javascript 1 Month ago.

Reply to " jester.js"

Here you can reply to the paste above