utils.js

From disqus.com, 1 Year ago, written in JavaScript, viewed 3 times. This paste is a reply to publisher-admin/js/entry.js from disqus.com - view diff
URL https://pastebin.freepbx.org/view/30ace1e7 Embed
Download Paste or View Raw
  1. define('core/utils',[
  2.     'jquery',
  3.     'underscore',
  4.  
  5.     'core/config',
  6.     'core/utils/browser',
  7. ], function (
  8.     $,
  9.     _,
  10.  
  11.     config,
  12.     browser
  13. ) {
  14.     'use strict';
  15.  
  16.     var doc = window.document;
  17.     // From https://github.com/ryanseddon/H5F/blob/039588f4b1d8513b09a49f903d70ff269435d4b3/src/H5F.js#L20
  18.     var emailPatt = /^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
  19.    var validateEmail = function (email) {
  20.        return emailPatt.test(email);
  21.    };
  22.  
  23.    /*
  24.     * This uses the same url RegExp as Bleach version 1.0.3 and returns
  25.     * the links it finds. This is not a direct match to Bleach, as there is no
  26.     * true HTML parsing, but it is sufficient for finding urls.
  27.     */
  28.    // TODO: config.TLDS is included to support an Embed override. Embed gets
  29.    // an up-to-date list every build via manifest.yaml and the interpolator;
  30.    // an equivalent system should be incorporated in next-core
  31.    var TLDS = config.TLDS ||
  32.        'zw|zuerich|zone|zm|zip|za|yt|youtube|yokohama|yoga|yodobashi|ye|' +
  33.        'yandex|yachts|xyz|xxx|xin|xerox|wtf|wtc|ws|world|works|work|wme|win|' +
  34.        'williamhill|wiki|wien|whoswho|wf|weir|wedding|wed|website|webcam|' +
  35.        'watch|wang|wales|vu|voyage|voto|voting|vote|vodka|vn|vlaanderen|' +
  36.        'vision|villas|video|viajes|vi|vg|vet|versicherung|ventures|vegas|ve|' +
  37.        'vc|vacations|va|uz|uy|us|uol|uno|university|uk|ug|ua|tz|tw|tv|tui|' +
  38.        'tt|trust|travel|training|trading|trade|tr|toys|town|tours|toshiba|' +
  39.        'toray|top|tools|tokyo|today|to|tn|tm|tl|tk|tj|tirol|tires|tips|' +
  40.        'tienda|tickets|theater|th|tg|tf|tennis|temasek|tel|technology|tech|' +
  41.        'team|td|tc|taxi|tax|tattoo|tatar|taipei|sz|systems|sydney|sy|sx|' +
  42.        'swiss|sv|suzuki|surgery|surf|support|supply|supplies|sucks|su|style|' +
  43.        'study|st|sr|spreadbetting|spiegel|space|soy|sony|solutions|solar|' +
  44.        'sohu|software|social|so|sn|sm|sl|sky|sk|sj|site|singles|si|shriram|' +
  45.        'show|shoes|shiksha|sh|sg|sexy|sex|sew|services|sener|seat|se|sd|' +
  46.        'scot|science|schwarz|schule|school|scholarships|schmidt|scb|sca|sc|' +
  47.        'sb|saxo|sarl|sap|samsung|sale|saarland|sa|ryukyu|rw|run|ruhr|ru|' +
  48.        'rsvp|rs|rodeo|rocks|ro|rip|rio|rich|reviews|review|restaurant|rest|' +
  49.        'republican|report|repair|rentals|rent|ren|reit|reisen|reise|rehab|' +
  50.        'redstone|red|recipes|realtor|re|racing|quebec|qpon|qa|py|pw|pub|pt|' +
  51.        'ps|property|properties|prof|productions|prod|pro|press|praxi|pr|' +
  52.        'post|porn|poker|pohl|pn|pm|plus|plumbing|place|pl|pk|pizza|pink|' +
  53.        'pictures|pictet|pics|piaget|physio|photos|photography|photo|philips|' +
  54.        'pharmacy|ph|pg|pf|pe|party|parts|partners|paris|panerai|page|pa|ovh|' +
  55.        'otsuka|osaka|organic|org|oracle|ooo|online|onl|ong|one|om|okinawa|' +
  56.        'nz|nyc|nu|ntt|nrw|nra|nr|np|no|nl|nissan|ninja|nico|ni|nhk|ngo|ng|' +
  57.        'nf|nexus|news|new|neustar|network|net|nec|ne|nc|navy|name|nagoya|' +
  58.        'nadex|na|mz|my|mx|mw|mv|museum|mu|mtpc|mtn|mt|ms|mr|mq|mp|movie|mov|' +
  59.        'motorcycles|moscow|mortgage|mormon|money|monash|moe|moda|mobi|mo|mn|' +
  60.        'mma|mm|ml|mk|mini|mil|miami|mh|mg|menu|memorial|meme|melbourne|meet|' +
  61.        'media|me|md|mc|marriott|markets|marketing|market|mango|management|' +
  62.        'maison|maif|madrid|ma|ly|lv|luxury|luxe|lu|ltda|lt|ls|lr|love|lotto|' +
  63.        'lotte|london|lol|loans|loan|lk|link|limo|limited|lighting|life|lidl|' +
  64.        'liaison|li|lgbt|legal|leclerc|lease|lds|lc|lb|lawyer|latrobe|lat|' +
  65.        'land|lacaixa|la|kz|kyoto|ky|kw|kred|krd|kr|kp|komatsu|koeln|kn|km|' +
  66.        'kiwi|kitchen|kim|ki|kh|kg|ke|kddi|kaufen|juegos|jp|joburg|jobs|jo|' +
  67.        'jm|jewelry|jetzt|je|jcb|java|iwc|it|is|irish|ir|iq|io|investments|' +
  68.        'international|int|insure|institute|ink|ing|info|infiniti|industries|' +
  69.        'in|immobilien|immo|im|il|ifm|ie|id|icu|ibm|hu|ht|hr|how|house|' +
  70.        'hosting|host|horse|honda|homes|holiday|holdings|hockey|hn|hm|hk|hiv|' +
  71.        'hitachi|hiphop|hermes|here|help|healthcare|haus|hangout|hamburg|gy|' +
  72.        'gw|guru|guitars|guide|guge|gu|gt|gs|gripe|green|gratis|graphics|gr|' +
  73.        'gq|gp|gov|gop|google|goog|goo|golf|goldpoint|gold|gn|gmx|gmo|gmail|' +
  74.        'gm|globo|global|gle|glass|gl|gives|gifts|gift|gi|gh|ggee|gg|gf|gent|' +
  75.        'ge|gdn|gd|gbiz|gb|garden|gallery|gal|ga|futbol|furniture|fund|' +
  76.        'frogans|frl|fr|foundation|forsale|forex|football|foo|fo|fm|fly|' +
  77.        'flsmidth|flowers|florist|flights|fk|fj|fitness|fit|fishing|fish|' +
  78.        'firmdale|financial|finance|film|fi|feedback|fashion|farm|fans|fan|' +
  79.        'faith|fail|express|exposed|expert|exchange|everbank|events|eus|' +
  80.        'eurovision|eu|et|estate|esq|es|erni|er|equipment|epson|enterprises|' +
  81.        'engineering|engineer|energy|emerck|email|eg|ee|education|edu|ec|eat|' +
  82.        'dz|dvag|durban|download|doosan|domains|doha|dog|docs|do|dnp|dm|dk|' +
  83.        'dj|discount|directory|direct|digital|diet|diamonds|dev|design|desi|' +
  84.        'dentist|dental|democrat|delivery|degree|deals|de|dclk|day|datsun|' +
  85.        'dating|date|dance|dad|dabur|cz|cyou|cymru|cy|cx|cw|cv|cuisinella|cu|' +
  86.        'cruises|crs|cricket|creditcard|credit|cr|courses|country|coop|cool|' +
  87.        'cooking|contractors|consulting|construction|condos|computer|company|' +
  88.        'community|com|cologne|college|coffee|codes|coach|co|cn|cm|club|' +
  89.        'clothing|clinic|click|cleaning|claims|cl|ck|city|citic|ci|church|' +
  90.        'chrome|christmas|chloe|cheap|chat|channel|ch|cg|cfd|cfa|cf|cern|ceo|' +
  91.        'center|cd|cc|cbn|catering|cat|casino|cash|casa|cartier|cars|careers|' +
  92.        'career|care|cards|caravan|capital|capetown|canon|cancerresearch|' +
  93.        'camp|camera|cal|cafe|cab|ca|bzh|bz|by|bw|bv|buzz|business|builders|' +
  94.        'build|budapest|bt|bs|brussels|brother|broker|bridgestone|br|' +
  95.        'boutique|boo|bond|boats|bo|bnpparibas|bn|bmw|bm|blue|bloomberg|' +
  96.        'blackfriday|black|bj|biz|bio|bingo|bike|bid|bi|bh|bg|bf|best|berlin|' +
  97.        'beer|be|bd|bbc|bb|bayern|bauhaus|bargains|barclays|barclaycard|bar|' +
  98.        'bank|band|ba|az|axa|ax|aw|autos|auto|audio|auction|au|attorney|at|' +
  99.        'associates|asia|as|arpa|army|archi|ar|aquarelle|aq|apartments|ao|' +
  100.        'android|an|amsterdam|am|alsace|allfinanz|al|airforce|aig|ai|agency|' +
  101.        'ag|afl|af|aero|ae|adult|ads|ad|actor|active|accountants|accountant|' +
  102.        'accenture|academy|ac|abogado|abbott|abb';
  103.  
  104.    // Url RegExp
  105.    var URL_RE = new RegExp(
  106.        // http://
  107.        // Note: First group must be removed from match when
  108.        // processing, in python it was a look-behind.
  109.        '([^@.]|^)\\b(?:\\w[\\w-]*:/{0,3}(?:(?:\\w+:)?\\w+@)?)?' +
  110.        // xx.yy.tld
  111.        '([\\w-]+\\.)+(?:' + TLDS + ')(?!\\.\\w)\\b' +
  112.        // optional port
  113.        '(?::\\d+)?' +
  114.        // /path/zz (excluding "unsafe" chars from RFC 1738,
  115.        // except for # and ~, which happen in practice)
  116.        '(?:[/?][^\\s\\{\\}\\|\\\\\\^\\[\\]`<>"\\x80-\\xFF\\x00-\\x1F\\x7F]*)?',
  117.        // Flags.
  118.        // Note: ignore case is NOT set because Bleach version 1.0.3 does not
  119.        // set it. This is a bug, resulting in urls being ignored if the TLD
  120.        // is capitalized. However, it is repeated here for consistency with
  121.        // the server; if we update Bleach we should update this method as well.
  122.        'g'
  123.    );
  124.  
  125.    var isUrl = function (urlStr) {
  126.        return Boolean(urlStr.match(URL_RE));
  127.    };
  128.  
  129.    // Protocol RegExp
  130.    var PROTO_RE = /^[\w-]+:\/{0,3}/;
  131.    // Punctuation RegExp.
  132.    // This is global so that lastIndex is set.
  133.    var PUNCT_RE = /([.,]+)$/g;
  134.  
  135.    var bleachFindUrls = function (message) {
  136.        var urlRecord = [];
  137.        var match, matchedStr, punctMatch, href, group1;
  138.  
  139.        if (!message)
  140.            return urlRecord;
  141.  
  142.        while (match = URL_RE.exec(message)) {  // eslint-disable-line no-cond-assign
  143.            matchedStr = match[0];
  144.            group1 = match[1];
  145.  
  146.            // Remove first group of match (see comment in URL_RE)
  147.            matchedStr = matchedStr.slice(group1.length);
  148.  
  149.            // Remove trailing punctuation
  150.            PUNCT_RE.lastIndex = 0;
  151.            punctMatch = PUNCT_RE.exec(matchedStr);
  152.            if (punctMatch)
  153.                matchedStr = matchedStr.slice(0, matchedStr.length - punctMatch[0].length);
  154.  
  155.            // Normalize protocol
  156.            if (PROTO_RE.test(matchedStr))
  157.                href = matchedStr;
  158.            else
  159.                href = 'http://' + matchedStr;
  160.  
  161.            // Store match
  162.            var index = match.index + group1.length;
  163.            urlRecord.push({
  164.                text: matchedStr,
  165.                url: href,
  166.                index: index,
  167.                endIndex: index + matchedStr.length,
  168.            });
  169.        }
  170.  
  171.        return urlRecord;
  172.    };
  173.  
  174.    // Regex to match sequence of 1 or more punctuation
  175.    // characters at the end of a string
  176.    // See: www.unicode.org/charts/
  177.    var terminatingPuncRe = new RegExp('[' +
  178.            // Basic Latin (ASCII punctuation blocks)
  179.            '\\u0021-\\u002F' +
  180.            '\\u003A-\\u0040' +
  181.            '\\u005B-\\u0060' +
  182.            '\\u007B-\\u007E' +
  183.            // Latin-1 Supplement (Latin-1 punctuation)
  184.            '\\u00A1-\\u00BF' +
  185.            // General Punctuation
  186.            '\\u2010-\\u2027' +
  187.            '\\u2030-\\u205E' +
  188.            // Miscellaneous technical
  189.            '\\u2300-\\u23FF' +
  190.            // Supplemental punctuation
  191.            '\\u2E00-\\u2E7F' +
  192.            // CJK Symbols and Punctuation
  193.            '\\u3001-\\u303F' +
  194.            // Vertical forms
  195.            '\\uFE10-\\uFE19' +
  196.            // CJK Compatibility Forms
  197.            '\\uFE30-\\uFE4F' +
  198.            // Small form variants
  199.            '\\uFE50-\\uFE6B' +
  200.            // Fullwidth ASCII Forms
  201.            '\\uFF01-\\uFF0F' +
  202.            '\\uFF1A-\\uFF20' +
  203.            '\\uFF3B-\\uFF40' +
  204.            '\\uFF5B-\\uFF60' +
  205.            // Halfwidth CJK Punctuation
  206.            '\\uFF5F-\\uFF64' +
  207.        ']+$');
  208.  
  209.    var MAX_TRUNCATION_RATIO = 0.5;
  210.    // Given a character limit (upperLimit) return the whole text
  211.    // if it fits within the limit, otherwise try to truncate
  212.    // within that limit without chopping off a word halfway or
  213.    // returning text with dangling punctuation but also without
  214.    // truncating the text more than halfway.
  215.    var niceTruncate = function (text, upperLimit) {
  216.        if (text.length <= upperLimit)
  217.            return text;
  218.  
  219.        text = text.slice(0, upperLimit - 1);  // account the ellipsis char
  220.        var max = text;
  221.  
  222.        // There's no way to know if the last sequence of chars is
  223.        // a whole word or not, so scan the sliced text backwards
  224.        // for the first whitespace character and truncate there
  225.  
  226.        // Greedily match everything up to the last chunk of whitespace
  227.        var matches = /(^.*\S)\s/.exec(text);
  228.  
  229.        if (matches)
  230.            text = matches[1];
  231.  
  232.        var endPunctuation = terminatingPuncRe.exec(text);
  233.  
  234.        // Remove any trailing punctuation
  235.        if (endPunctuation)
  236.            text = text.slice(0, text.length - endPunctuation[0].length);
  237.  
  238.        // If the further truncation above caused the text we're returning
  239.        // to be less than 1/2 what it was before further truncation, we undo
  240.        if (text.length < MAX_TRUNCATION_RATIO * max.length)
  241.            text = max;
  242.  
  243.        return text + '\u2026';  // Ellipsis
  244.    };
  245.  
  246.    var _hasStyleProperty = (function () {
  247.        var el = doc.createElement('fakeelement');
  248.  
  249.        return function (_cssName, jsName) {
  250.            return el.style[jsName] !== undefined;
  251.        };
  252.    }());
  253.  
  254.    // http://stackoverflow.com/questions/5023514/how-do-i-normalize-css3-transition-functions-across-browsers
  255.    var transitionEndEvent = (function () {
  256.        var transitions = {
  257.            transition: 'transitionend',
  258.            OTransition: 'otransitionend',
  259.            MozTransition: 'transitionend',
  260.            WebkitTransition: 'webkitTransitionEnd',
  261.        };
  262.  
  263.        return _.find(transitions, _hasStyleProperty) || null;
  264.    })();
  265.  
  266.    // https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations/Detecting_CSS_animation_support
  267.    var animationEndEvent = (function () {
  268.        var animations = {
  269.            animation: 'animationend',
  270.            OAnimation: 'oAnimationEnd',
  271.            MozAnimation: 'animationend',
  272.            WebkitAnimation: 'webkitAnimationEnd',
  273.        };
  274.  
  275.        return _.find(animations, _hasStyleProperty) || null;
  276.    })();
  277.  
  278.    /**
  279.     * Does the current device publish a mobile-like user agent (phone & tablet)?
  280.     * Ported from https://gist.github.com/dalethedeveloper/1503252
  281.     *
  282.     * @param {window} [win] dependency injection for the main window global :|
  283.     * @returns {boolean} `true` if the browser looks like a mobile browser, `false` otherwise
  284.     */
  285.    var isMobileUserAgent = function (win) {
  286.        win = win || window;
  287.        return /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/i.test(win.navigator.userAgent || win.navigator.vendor || win.opera);
  288.    };
  289.  
  290.    /**
  291.     * Utility helper for DOM event handlers that automatically calls preventDefault for you
  292.     *
  293.     * @param {function} handler The event handler to be wrapped/modified
  294.     * @returns {function} The new, augmented event handler that prevents the default action for the event
  295.     */
  296.    function preventDefaultHandler(handler) {
  297.        return function (evt) {
  298.            if (evt && evt.preventDefault)
  299.                evt.preventDefault();
  300.            return handler.apply(this, arguments);
  301.        };
  302.    }
  303.  
  304.    /**
  305.     * Utility helper for DOM event handlers that automatically calls stopPropagation for you
  306.     *
  307.     * @param {function} handler The event handler to be wrapped/modified
  308.     * @returns {function} The new, augmented event handler that stops the propagation of the event
  309.     */
  310.    function stopPropagationHandler(handler) {
  311.        return function (evt) {
  312.            if (evt && evt.stopPropagation)
  313.                evt.stopPropagation();
  314.            return handler.apply(this, arguments);
  315.        };
  316.    }
  317.  
  318.    function stopEventHandler(handler) {
  319.        return preventDefaultHandler(stopPropagationHandler(handler));
  320.    }
  321.  
  322.    function getDomain(url) {
  323.        // Extracts hostname from url, without the www prefix.
  324.  
  325.        if (!url)
  326.            return '';
  327.  
  328.        // Force the protocol to http.
  329.        // This resolves an issue where some browsers do not extract
  330.        // the hostname if the url does not use a typical protocol.
  331.        // Forcing a protocol is also required since if missing the
  332.        // url will be resolved as a relative url on our domain.
  333.        url = 'http://' + url.replace(/^([a-z+.-]+:)?\/+/i, '');
  334.  
  335.        var link = doc.createElement('a');
  336.        link.href = url;
  337.  
  338.        // Remove www prefix and any trailing numbers.
  339.        // Since getDomain is used only for display purposes this is a
  340.        // safe operation.
  341.        var domain = link.hostname.replace(/^www\d*\./i, '');
  342.  
  343.        // Normalize capitalization since browsers are inconsistent
  344.        // about this.
  345.        domain = domain.toLowerCase();
  346.  
  347.        return domain;
  348.    }
  349.  
  350.    function serializeArgs(params) {
  351.        var pcs = [];
  352.        _.each(params, function (val, key) {
  353.            if (val !== undefined)
  354.                pcs.push(key + (val === null ? '' : '=' + encodeURIComponent(val)));
  355.        });
  356.        return pcs.join('&');
  357.    }
  358.  
  359.    function serialize(url, params, nocache) {
  360.        if (params) {
  361.            if (url.indexOf('?') === -1)
  362.                url += '?';
  363.            else if (url.charAt(url.length - 1) !== '&')
  364.                url += '&';
  365.  
  366.            url += this.serializeArgs(params);
  367.        }
  368.  
  369.        if (nocache) {
  370.            var ncp = {};
  371.            ncp[(new Date()).getTime()] = null;
  372.            return this.serialize(url, ncp);
  373.        }
  374.  
  375.        var len = url.length;
  376.        return url.charAt(len - 1) === '&' ? url.slice(0, len - 1) : url;
  377.    }
  378.  
  379.    /**
  380.     * window.open wrapper
  381.     *
  382.     * IMPORTANT: must obey same contract as window.open
  383.     * i.e., same function signature, same return value
  384.     *
  385.     * We wrap it because it is not possible to stub `window.open`
  386.     * reliably across browsers for testing, which causes issues from time to time.
  387.     *
  388.     * @param {string} url The URL for the new popup window
  389.     * @param {string} [title] The title of the new popup window
  390.     * @param {Object} [options] Options for the new window such as height and width. The following are overridden:
  391.     *                           location, status, resizable, scrollbars for UX and cross-browser consistency.
  392.     * @returns {window|null} The reference to the newly created popup window, or `null` if popup is blocked.
  393.     */
  394.    function openWindow(url, title, options) {
  395.        // Don't add any defaults if options object is not provided. Not using
  396.        // options is the only way to default to opening a new tab instead of a
  397.        // window when using `window.open`
  398.        if (options) {
  399.            _.extend(options, {
  400.                'location': 1,
  401.                'status': 1,
  402.                'resizable': 1,
  403.                'scrollbars': 1,
  404.            });
  405.        } else {
  406.            options = {};
  407.        }
  408.  
  409.        if (options.width && options.height) {
  410.            // By default, position window in the middle of the browser screen
  411.            _.defaults(options, {
  412.                left: window.screen.width / 2 - options.width / 2,
  413.                top: window.screen.height / 2 - options.height / 2,
  414.            });
  415.        }
  416.  
  417.        var optionsStr = _.map(options, function (val, key) {
  418.            return key + '=' + val;
  419.        }).join(',');
  420.  
  421.        return window.open(url, title, optionsStr);
  422.    }
  423.  
  424.    /**
  425.     * Safely insert a string into another string at specified index.
  426.     * Spaces will be guaranteed to surround the inserted string, except
  427.     * at the beginning of the new string.
  428.     *
  429.     * @param {string} string The string to be inserted into
  430.     * @param {number} index The position to insert into
  431.     * @param {string} stringToInsert The string to be inserted
  432.     *
  433.     * @returns {string} The newly crafted string
  434.     */
  435.    function insertWithWhitespace(string, index, stringToInsert) {
  436.        if (index < 0)
  437.            index = 0;
  438.  
  439.        var before = string.substring(0, index);
  440.        var after = string.substring(index);
  441.  
  442.        // Place a space before the new string if necessary
  443.        if (before.length && !/\s$/.test(before))
  444.            before += ' ';
  445.  
  446.        // Place a space after the new string if necessary
  447.        // Will also place a space if at the end of the text
  448.        if (!/^\s/.test(after))
  449.            after = ' ' + after;
  450.  
  451.        return before + stringToInsert + after;
  452.    }
  453.  
  454.    /**
  455.     * Check if a clicked link will open a new window or tab.
  456.     *
  457.     * We don't have to delay link clicks if they will open a new tab via
  458.     * command / shift / control key modifiers or if the 'target' attribute is '_blank'.
  459.     *
  460.     * @param  {$.Event}    evt The event object from the original click event.
  461.     * @param  {jQuery}   $link jQuery wrapped link object.
  462.     * @returns {boolean}
  463.     */
  464.    var willOpenNewWindow = function (evt, $link) {
  465.        if (!$link)
  466.            $link = $(evt.currentTarget);
  467.  
  468.        return $link.attr('target') === '_blank' ||
  469.            evt.ctrlKey ||  // For Windows and Linux
  470.            evt.metaKey || // For OS X
  471.            evt.shiftKey || // For new window
  472.            evt.altKey;  // God knows what
  473.    };
  474.  
  475.    var LINK_CLICK_RECENCY_TIMEOUT = 500;  /* ms */
  476.    /**
  477.     * Determine if a click event should be logged to our analytics servers.
  478.     *
  479.     * We currently log clicks only if the link's href is intended to cause
  480.     * the parent page to change locations (disregarding modifier keys, etc.).
  481.     *
  482.     * @param  {$.Event}  evt The jQuery event object.
  483.     * @param  {jQuery}   $link jQuery wrapped link object.
  484.     * @returns {boolean}
  485.     */
  486.    var clickShouldBeLogged = (function () {
  487.        var logged = {};
  488.        var urlFragmentReg = /#.*$/;
  489.  
  490.        var getLinkTrackingId = function ($link) {
  491.            // Because a link's href may be modified during the course
  492.            // of a click event, we need to attach our own IDs.
  493.            var id = $link.attr('data-tid');
  494.            if (!id) {
  495.                id = _.uniqueId();
  496.                $link.attr('data-tid', id);
  497.            }
  498.            return id;
  499.        };
  500.  
  501.        return function (evt, $link) {
  502.            // We don't do anything if we're already handling this event elsewhere.
  503.            if (evt.isDefaultPrevented())
  504.                return false;
  505.  
  506.            // We don't bother if the clicked element is not a link.
  507.            if (!$link.is('a'))
  508.                return false;
  509.  
  510.            // We don't bother if the clicked link doesn't have an href attribute,
  511.            // or if the clicked link's href attribute is just a hash.
  512.            var href = ($link.attr('href') || '').replace(urlFragmentReg, '');
  513.            if (!href)
  514.                return false;
  515.  
  516.            // Because we re-trigger clicks, it is very possible that we're being
  517.            // asked to log the same click twice. We keep an internal hash of
  518.            // links clicks we've logged within the last .5s so that we don't
  519.            // enter an infinite click loop.
  520.            var linkId = getLinkTrackingId($link);
  521.            var timestamp = new Date().getTime();
  522.  
  523.            // If we recently delayed this click, then bail out now.
  524.            if (logged[linkId] && timestamp - logged[linkId] < LINK_CLICK_RECENCY_TIMEOUT)
  525.                return false;
  526.  
  527.            logged[linkId] = timestamp;
  528.            return true;
  529.        };
  530.    })();
  531.  
  532.    return {
  533.        validateEmail: validateEmail,
  534.        isUrl: isUrl,
  535.        bleachFindUrls: bleachFindUrls,
  536.        niceTruncate: niceTruncate,
  537.        transitionEndEvent: transitionEndEvent,
  538.        animationEndEvent: animationEndEvent,
  539.        isMobileUserAgent: isMobileUserAgent,
  540.        preventDefaultHandler: preventDefaultHandler,
  541.        stopPropagationHandler: stopPropagationHandler,
  542.        stopEventHandler: stopEventHandler,
  543.        getDomain: getDomain,
  544.        serializeArgs: serializeArgs,
  545.        serialize: serialize,
  546.        openWindow: openWindow,
  547.        insertWithWhitespace: insertWithWhitespace,
  548.        willOpenNewWindow: willOpenNewWindow,
  549.        clickShouldBeLogged: clickShouldBeLogged,
  550.        browser: browser,
  551.    };
  552. });
  553.  
  554. // https://c.disquscdn.com/next/next-core/core/utils.js

Replies to utils.js rss

Title Name Language When
Events.js disqus.com javascript 1 Year ago.

Reply to "utils.js"

Here you can reply to the paste above