index.js 1.5 KB

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