punycode: update to v1.3.2
authorMathias Bynens <mathias@qiwi.be>
Fri, 28 Nov 2014 09:50:12 +0000 (10:50 +0100)
committerFedor Indutny <fedor@indutny.com>
Fri, 28 Nov 2014 10:21:43 +0000 (13:21 +0300)
Changes since v1.2.3:

* Email address support in `toASCII` and `toUnicode`
* `punycode.ucs2.encode` now no longer mutates the `codePoints`
  argument
* Ensure trailing `.` in domain names are preserved
* Some minor code cleanup + bug fixes

Reviewed-By: Fedor Indutny <fedor@indutny.com>
PR-URL: https://github.com/iojs/io.js/pull/6

lib/punycode.js

index 8a95955..82cc207 100644 (file)
@@ -1,12 +1,17 @@
-/*! http://mths.be/punycode v1.2.3 by @mathias */
+/*! https://mths.be/punycode v1.3.2 by @mathias */
 ;(function(root) {
 
        /** Detect free variables */
-       var freeExports = typeof exports == 'object' && exports;
+       var freeExports = typeof exports == 'object' && exports &&
+               !exports.nodeType && exports;
        var freeModule = typeof module == 'object' && module &&
-               module.exports == freeExports && module;
+               !module.nodeType && module;
        var freeGlobal = typeof global == 'object' && global;
-       if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
+       if (
+               freeGlobal.global === freeGlobal ||
+               freeGlobal.window === freeGlobal ||
+               freeGlobal.self === freeGlobal
+       ) {
                root = freeGlobal;
        }
 
@@ -32,8 +37,8 @@
 
        /** Regular expressions */
        regexPunycode = /^xn--/,
-       regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
-       regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
+       regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
+       regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
 
        /** Error messages */
        errors = {
         */
        function map(array, fn) {
                var length = array.length;
+               var result = [];
                while (length--) {
-                       array[length] = fn(array[length]);
+                       result[length] = fn(array[length]);
                }
-               return array;
+               return result;
        }
 
        /**
-        * A simple `Array#map`-like wrapper to work with domain name strings.
+        * A simple `Array#map`-like wrapper to work with domain name strings or email
+        * addresses.
         * @private
-        * @param {String} domain The domain name.
+        * @param {String} domain The domain name or email address.
         * @param {Function} callback The function that gets called for every
         * character.
         * @returns {Array} A new string of characters returned by the callback
         * function.
         */
        function mapDomain(string, fn) {
-               return map(string.split(regexSeparators), fn).join('.');
+               var parts = string.split('@');
+               var result = '';
+               if (parts.length > 1) {
+                       // In email addresses, only the domain name should be punycoded. Leave
+                       // the local part (i.e. everything up to `@`) intact.
+                       result = parts[0] + '@';
+                       string = parts[1];
+               }
+               // Avoid `split(regex)` for IE8 compatibility. See #17.
+               string = string.replace(regexSeparators, '\x2E');
+               var labels = string.split('.');
+               var encoded = map(labels, fn).join('.');
+               return result + encoded;
        }
 
        /**
         * UCS-2 exposes as separate characters) into a single code point,
         * matching UTF-16.
         * @see `punycode.ucs2.encode`
-        * @see <http://mathiasbynens.be/notes/javascript-encoding>
+        * @see <https://mathiasbynens.be/notes/javascript-encoding>
         * @memberOf punycode.ucs2
         * @name decode
         * @param {String} string The Unicode input string (UCS-2).
 
        /**
         * Bias adaptation function as per section 3.4 of RFC 3492.
-        * http://tools.ietf.org/html/rfc3492#section-3.4
+        * https://tools.ietf.org/html/rfc3492#section-3.4
         * @private
         */
        function adapt(delta, numPoints, firstTime) {
        }
 
        /**
-        * Converts a string of Unicode symbols to a Punycode string of ASCII-only
-        * symbols.
+        * Converts a string of Unicode symbols (e.g. a domain name label) to a
+        * Punycode string of ASCII-only symbols.
         * @memberOf punycode
         * @param {String} input The string of Unicode symbols.
         * @returns {String} The resulting Punycode string of ASCII-only symbols.
        }
 
        /**
-        * Converts a Punycode string representing a domain name to Unicode. Only the
-        * Punycoded parts of the domain name will be converted, i.e. it doesn't
-        * matter if you call it on a string that has already been converted to
-        * Unicode.
+        * Converts a Punycode string representing a domain name or an email address
+        * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
+        * it doesn't matter if you call it on a string that has already been
+        * converted to Unicode.
         * @memberOf punycode
-        * @param {String} domain The Punycode domain name to convert to Unicode.
+        * @param {String} input The Punycoded domain name or email address to
+        * convert to Unicode.
         * @returns {String} The Unicode representation of the given Punycode
         * string.
         */
-       function toUnicode(domain) {
-               return mapDomain(domain, function(string) {
+       function toUnicode(input) {
+               return mapDomain(input, function(string) {
                        return regexPunycode.test(string)
                                ? decode(string.slice(4).toLowerCase())
                                : string;
        }
 
        /**
-        * Converts a Unicode string representing a domain name to Punycode. Only the
-        * non-ASCII parts of the domain name will be converted, i.e. it doesn't
-        * matter if you call it with a domain that's already in ASCII.
+        * Converts a Unicode string representing a domain name or an email address to
+        * Punycode. Only the non-ASCII parts of the domain name will be converted,
+        * i.e. it doesn't matter if you call it with a domain that's already in
+        * ASCII.
         * @memberOf punycode
-        * @param {String} domain The domain name to convert, as a Unicode string.
-        * @returns {String} The Punycode representation of the given domain name.
+        * @param {String} input The domain name or email address to convert, as a
+        * Unicode string.
+        * @returns {String} The Punycode representation of the given domain name or
+        * email address.
         */
-       function toASCII(domain) {
-               return mapDomain(domain, function(string) {
+       function toASCII(input) {
+               return mapDomain(input, function(string) {
                        return regexNonASCII.test(string)
                                ? 'xn--' + encode(string)
                                : string;
                 * @memberOf punycode
                 * @type String
                 */
-               'version': '1.2.3',
+               'version': '1.3.2',
                /**
                 * An object of methods to convert from JavaScript's internal character
                 * representation (UCS-2) to Unicode code points, and back.
-                * @see <http://mathiasbynens.be/notes/javascript-encoding>
+                * @see <https://mathiasbynens.be/notes/javascript-encoding>
                 * @memberOf punycode
                 * @type Object
                 */
                typeof define.amd == 'object' &&
                define.amd
        ) {
-               define(function() {
+               define('punycode', function() {
                        return punycode;
                });
-       }       else if (freeExports && !freeExports.nodeType) {
-               if (freeModule) { // in Node.js or RingoJS v0.8.0+
+       } else if (freeExports && freeModule) {
+               if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
                        freeModule.exports = punycode;
                } else { // in Narwhal or RingoJS v0.7.0-
                        for (key in punycode) {