Url.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. var Class = require('./Class');
  2. var extend = require('./extend');
  3. var trim = require('./trim');
  4. var query = require('./query');
  5. var isEmpty = require('./isEmpty');
  6. var each = require('./each');
  7. var isArr = require('./isArr');
  8. var toArr = require('./toArr');
  9. var isBrowser = require('./isBrowser');
  10. var isObj = require('./isObj');
  11. var toStr = require('./toStr');
  12. exports = Class(
  13. {
  14. className: 'Url',
  15. initialize: function(url) {
  16. if (!url && isBrowser) url = window.location.href;
  17. extend(this, exports.parse(url || ''));
  18. },
  19. setQuery: function(name, val) {
  20. var query = this.query;
  21. if (isObj(name)) {
  22. each(name, function(val, key) {
  23. query[key] = toStr(val);
  24. });
  25. } else {
  26. query[name] = toStr(val);
  27. }
  28. return this;
  29. },
  30. rmQuery: function(name) {
  31. var query = this.query;
  32. if (!isArr(name)) name = toArr(name);
  33. each(name, function(key) {
  34. delete query[key];
  35. });
  36. return this;
  37. },
  38. toString: function() {
  39. return exports.stringify(this);
  40. }
  41. },
  42. {
  43. parse: function(url) {
  44. var ret = {
  45. protocol: '',
  46. auth: '',
  47. hostname: '',
  48. hash: '',
  49. query: {},
  50. port: '',
  51. pathname: '',
  52. slashes: false
  53. };
  54. var rest = trim(url);
  55. var slashes = false;
  56. var proto = rest.match(regProto);
  57. if (proto) {
  58. proto = proto[0];
  59. ret.protocol = proto.toLowerCase();
  60. rest = rest.substr(proto.length);
  61. }
  62. if (proto) {
  63. slashes = rest.substr(0, 2) === '//';
  64. if (slashes) {
  65. rest = rest.slice(2);
  66. ret.slashes = true;
  67. }
  68. }
  69. if (slashes) {
  70. var host = rest;
  71. var hostEnd = -1;
  72. for (var i = 0, len = hostEndingChars.length; i < len; i++) {
  73. var pos = rest.indexOf(hostEndingChars[i]);
  74. if (pos !== -1 && (hostEnd === -1 || pos < hostEnd))
  75. hostEnd = pos;
  76. }
  77. if (hostEnd > -1) {
  78. host = rest.slice(0, hostEnd);
  79. rest = rest.slice(hostEnd);
  80. }
  81. var atSign = host.lastIndexOf('@');
  82. if (atSign !== -1) {
  83. ret.auth = decodeURIComponent(host.slice(0, atSign));
  84. host = host.slice(atSign + 1);
  85. }
  86. ret.hostname = host;
  87. var port = host.match(regPort);
  88. if (port) {
  89. port = port[0];
  90. if (port !== ':') ret.port = port.substr(1);
  91. ret.hostname = host.substr(0, host.length - port.length);
  92. }
  93. }
  94. var hash = rest.indexOf('#');
  95. if (hash !== -1) {
  96. ret.hash = rest.substr(hash);
  97. rest = rest.slice(0, hash);
  98. }
  99. var queryMark = rest.indexOf('?');
  100. if (queryMark !== -1) {
  101. ret.query = query.parse(rest.substr(queryMark + 1));
  102. rest = rest.slice(0, queryMark);
  103. }
  104. ret.pathname = rest || '/';
  105. return ret;
  106. },
  107. stringify: function(obj) {
  108. var ret =
  109. obj.protocol +
  110. (obj.slashes ? '//' : '') +
  111. (obj.auth ? encodeURIComponent(obj.auth) + '@' : '') +
  112. obj.hostname +
  113. (obj.port ? ':' + obj.port : '') +
  114. obj.pathname;
  115. if (!isEmpty(obj.query)) ret += '?' + query.stringify(obj.query);
  116. if (obj.hash) ret += obj.hash;
  117. return ret;
  118. }
  119. }
  120. );
  121. var regProto = /^([a-z0-9.+-]+:)/i;
  122. var regPort = /:[0-9]*$/;
  123. var hostEndingChars = ['/', '?', '#'];
  124. module.exports = exports;