You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.1 KiB

2 years ago
var Class = require('./Class');
var extend = require('./extend');
var trim = require('./trim');
var query = require('./query');
var isEmpty = require('./isEmpty');
var each = require('./each');
var isArr = require('./isArr');
var toArr = require('./toArr');
var isBrowser = require('./isBrowser');
var isObj = require('./isObj');
var toStr = require('./toStr');
exports = Class(
{
className: 'Url',
initialize: function(url) {
if (!url && isBrowser) url = window.location.href;
extend(this, exports.parse(url || ''));
},
setQuery: function(name, val) {
var query = this.query;
if (isObj(name)) {
each(name, function(val, key) {
query[key] = toStr(val);
});
} else {
query[name] = toStr(val);
}
return this;
},
rmQuery: function(name) {
var query = this.query;
if (!isArr(name)) name = toArr(name);
each(name, function(key) {
delete query[key];
});
return this;
},
toString: function() {
return exports.stringify(this);
}
},
{
parse: function(url) {
var ret = {
protocol: '',
auth: '',
hostname: '',
hash: '',
query: {},
port: '',
pathname: '',
slashes: false
};
var rest = trim(url);
var slashes = false;
var proto = rest.match(regProto);
if (proto) {
proto = proto[0];
ret.protocol = proto.toLowerCase();
rest = rest.substr(proto.length);
}
if (proto) {
slashes = rest.substr(0, 2) === '//';
if (slashes) {
rest = rest.slice(2);
ret.slashes = true;
}
}
if (slashes) {
var host = rest;
var hostEnd = -1;
for (var i = 0, len = hostEndingChars.length; i < len; i++) {
var pos = rest.indexOf(hostEndingChars[i]);
if (pos !== -1 && (hostEnd === -1 || pos < hostEnd))
hostEnd = pos;
}
if (hostEnd > -1) {
host = rest.slice(0, hostEnd);
rest = rest.slice(hostEnd);
}
var atSign = host.lastIndexOf('@');
if (atSign !== -1) {
ret.auth = decodeURIComponent(host.slice(0, atSign));
host = host.slice(atSign + 1);
}
ret.hostname = host;
var port = host.match(regPort);
if (port) {
port = port[0];
if (port !== ':') ret.port = port.substr(1);
ret.hostname = host.substr(0, host.length - port.length);
}
}
var hash = rest.indexOf('#');
if (hash !== -1) {
ret.hash = rest.substr(hash);
rest = rest.slice(0, hash);
}
var queryMark = rest.indexOf('?');
if (queryMark !== -1) {
ret.query = query.parse(rest.substr(queryMark + 1));
rest = rest.slice(0, queryMark);
}
ret.pathname = rest || '/';
return ret;
},
stringify: function(obj) {
var ret =
obj.protocol +
(obj.slashes ? '//' : '') +
(obj.auth ? encodeURIComponent(obj.auth) + '@' : '') +
obj.hostname +
(obj.port ? ':' + obj.port : '') +
obj.pathname;
if (!isEmpty(obj.query)) ret += '?' + query.stringify(obj.query);
if (obj.hash) ret += obj.hash;
return ret;
}
}
);
var regProto = /^([a-z0-9.+-]+:)/i;
var regPort = /:[0-9]*$/;
var hostEndingChars = ['/', '?', '#'];
module.exports = exports;