var Url = function (url, merge_with_current) {
url = url || "";
this.parse(url, merge_with_current);
};
$.extend(Url, {
default_ports: {
http: 80,
https: 443
},
regexp: /^(([a-z0-9_.-]+\:)?(\/\/([^\/#\?@:]+))?(:\d+)?)?([^\?#]+)?(\?[^#]*)?(#.*)?$/i,
parseQuery: function (query) {
var params = {},
pairs = query.split(/&|&|;/);
for (var i = 0; i < pairs.length; ++i) {
var k, v = null;
var idx = pairs[i].indexOf('=');
if (idx != -1) {
k = decodeURIComponent(pairs[i].substr(0, idx));
v = decodeURIComponent(pairs[i].substr(idx + 1));
} else {
k = decodeURIComponent(pairs[i]);
v = null;
}
if (k.length) {
if (params[k] !== undefined) {
if (!(params[k] instanceof Array))
params[k] = [params[k], v]
else
params.push(v);
} else
params[k] = v;
}
}
return params;
},
});
$.extend(Url.prototype, {
parse: function (url, merge_with_current) {
var m = url.match(Url.regexp) || [];
this.scheme = m[2] || '';
this.domain = m[4] || '';
this.port = m[5] || '';
this.path = m[6] || '';
this.query = m[7] || '';
this.hash = m[8] || '';
if (merge_with_current) {
// Мержим относительный URL с текущим
this._mergeWithCurrent();
}
this.domain = this.domain.toLowerCase();
this.scheme = this.scheme.substr(0, this.scheme.length - 1).toLowerCase();
this.port = this.port.substr(1);
this.query = this.query.substr(1);
this.hash = this.hash.substr(1);
this.query = Url.parseQuery(this.query);
return this;
},
isSame: function (url) {
return this.url(true) === url.url(true);
},
_mergeWithCurrent: function () {
var c = window.location;
if (!this.scheme.length) {
this.scheme = c.protocol;
if (!this.domain.length) {
this.domain = c.hostname;
if (!this.path.length) {
this.path = window.location.pathname;
if (!this.query.length) {
this.query = c.search;
if (!this.hash.length)
this.hash = c.hash;
}
} else if (this.path.substr(0, 1) != '/') {
this.path = c.pathname +
(c.pathname.substr(c.pathname.length - 1) == "/" ? "" : "/") +
this.path;
}
}
}
},
url: function (skip_hash) {
var url = "";
if (this.scheme.length)
url += this.scheme + ":";
if (this.domain.length || this.port.length) {
url += "//";
if (this.domain.length)
url += this.domain;
if (this.port.length)
url += ":" + this.port;
}
if (this.path.length)
url += this.path;
if (!$.isEmptyObject(this.query)) {
var first = true;
for (var key in this.query) {
if (typeof this.query[key] == 'array') {
for (var i = 0; i < this.query[key].length; ++i)
url += (first ? "?" : "&") + encodeURIComponent(key) + "=" + encodeURIComponent(this.query[key]);
if (first) first = false;
} else {
url += (first ? "?" : "&") + encodeURIComponent(key) + "=" + encodeURIComponent(this.query[key]);
if (first) first = false;
}
}
}
if (this.hash.length && !skip_hash)
url += "#" + this.hash;
return url;
},
parseDomain: function() {
var m, out = {domain: this.domain, sub_domain: "", sub_domains: [], base_domain: ""};
if ((m = this.domain.match(/((.*?)\.|^)([^\.]+\.[^\.]+)$/))) {
if (m[2] !== undefined) {
out.sub_domain = m[2].toLowerCase();
out.sub_domains = out.sub_domain.split('.');
}
if (m[3] !== undefined)
out.base_domain = m[3].toLowerCase();
}
return out;
}
});