utils.js

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

Replies to utils.js rss

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

Reply to "utils.js"

Here you can reply to the paste above