normalize-uri.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. 'use strict'
  2. var asciiAlphanumeric = require('../character/ascii-alphanumeric.js')
  3. var codes = require('../character/codes.js')
  4. var values = require('../character/values.js')
  5. var fromCharCode = require('../constant/from-char-code.js')
  6. // Encode unsafe characters with percent-encoding, skipping already
  7. // encoded sequences.
  8. function normalizeUri(value) {
  9. var index = -1
  10. var result = []
  11. var start = 0
  12. var skip = 0
  13. var code
  14. var next
  15. var replace
  16. while (++index < value.length) {
  17. code = value.charCodeAt(index)
  18. // A correct percent encoded value.
  19. if (
  20. code === codes.percentSign &&
  21. asciiAlphanumeric(value.charCodeAt(index + 1)) &&
  22. asciiAlphanumeric(value.charCodeAt(index + 2))
  23. ) {
  24. skip = 2
  25. }
  26. // ASCII.
  27. else if (code < 128) {
  28. if (!/[!#$&-;=?-Z_a-z~]/.test(fromCharCode(code))) {
  29. replace = fromCharCode(code)
  30. }
  31. }
  32. // Astral.
  33. else if (code > 55295 && code < 57344) {
  34. next = value.charCodeAt(index + 1)
  35. // A correct surrogate pair.
  36. if (code < 56320 && next > 56319 && next < 57344) {
  37. replace = fromCharCode(code, next)
  38. skip = 1
  39. }
  40. // Lone surrogate.
  41. else {
  42. replace = values.replacementCharacter
  43. }
  44. }
  45. // Unicode.
  46. else {
  47. replace = fromCharCode(code)
  48. }
  49. if (replace) {
  50. result.push(value.slice(start, index), encodeURIComponent(replace))
  51. start = index + skip + 1
  52. replace = undefined
  53. }
  54. if (skip) {
  55. index += skip
  56. skip = 0
  57. }
  58. }
  59. return result.join('') + value.slice(start)
  60. }
  61. module.exports = normalizeUri