index.js (1586B)
1 /*! 2 * encodeurl 3 * Copyright(c) 2016 Douglas Christopher Wilson 4 * MIT Licensed 5 */ 6 7 'use strict' 8 9 /** 10 * Module exports. 11 * @public 12 */ 13 14 module.exports = encodeUrl 15 16 /** 17 * RegExp to match non-URL code points, *after* encoding (i.e. not including "%") 18 * and including invalid escape sequences. 19 * @private 20 */ 21 22 var ENCODE_CHARS_REGEXP = /(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7A\x7E]|%(?:[^0-9A-Fa-f]|[0-9A-Fa-f][^0-9A-Fa-f]|$))+/g 23 24 /** 25 * RegExp to match unmatched surrogate pair. 26 * @private 27 */ 28 29 var UNMATCHED_SURROGATE_PAIR_REGEXP = /(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g 30 31 /** 32 * String to replace unmatched surrogate pair with. 33 * @private 34 */ 35 36 var UNMATCHED_SURROGATE_PAIR_REPLACE = '$1\uFFFD$2' 37 38 /** 39 * Encode a URL to a percent-encoded form, excluding already-encoded sequences. 40 * 41 * This function will take an already-encoded URL and encode all the non-URL 42 * code points. This function will not encode the "%" character unless it is 43 * not part of a valid sequence (`%20` will be left as-is, but `%foo` will 44 * be encoded as `%25foo`). 45 * 46 * This encode is meant to be "safe" and does not throw errors. It will try as 47 * hard as it can to properly encode the given URL, including replacing any raw, 48 * unpaired surrogate pairs with the Unicode replacement character prior to 49 * encoding. 50 * 51 * @param {string} url 52 * @return {string} 53 * @public 54 */ 55 56 function encodeUrl (url) { 57 return String(url) 58 .replace(UNMATCHED_SURROGATE_PAIR_REGEXP, UNMATCHED_SURROGATE_PAIR_REPLACE) 59 .replace(ENCODE_CHARS_REGEXP, encodeURI) 60 }