-
-
Save nutbread/ecc6d75f19db3e95ce91 to your computer and use it in GitHub Desktop.
A class to parse and resolve URLs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var URLParser = (function () { | |
// Return class | |
var URLParser = function (url_str) { | |
this.hash = ""; | |
this.host = null; | |
this.hostname = null; | |
this.pathname = ""; | |
this.protocol = null; | |
this.search = ""; | |
this.slashes = false; | |
this.auth = null; | |
this.port = null; | |
if (typeof(url_str) === "string") { | |
this.parse(url_str); | |
} | |
}; | |
// Regex | |
var re_protocol = /^[a-z][a-z0-9\+\-\.]*:/i, | |
re_double_slash = /^\/{2}/, | |
re_auth = /^(.*)@/i, | |
re_port = /:(\d*)$/i, | |
re_hierarchy_sep = /([\/\?\#]|$)/, | |
re_path_sep = /([\?\#]|$)/, | |
re_search_sep = /([\#]|$)/; | |
// Path operations | |
var normalize_path = function (path) { | |
return path; | |
}; | |
var join_paths = function (base, ext) { | |
if (ext[0] === "/") { | |
// Absolute | |
return ext; | |
} | |
// Joined | |
var p = base.lastIndexOf("/"); | |
if (p < 0) { | |
// Absolute | |
return ext; | |
} | |
// Join | |
return base.substr(0, p + 1) + ext; | |
}; | |
// Functions | |
URLParser.prototype = { | |
constructor: URLParser, | |
parse: function (url_str, ignore_double_slash) { | |
// Setup object | |
var m, url_part; | |
// Protocol | |
if ((m = re_protocol.exec(url_str)) !== null) { | |
this.protocol = m[0].toLowerCase(); | |
url_str = url_str.substr(m[0].length); | |
} | |
else { | |
this.protocol = null; | |
} | |
// Slashes | |
if (!ignore_double_slash && (m = re_double_slash.exec(url_str)) !== null) { | |
// Process auth and host | |
this.slashes = true; | |
url_str = url_str.substr(m[0].length); | |
// Find end | |
m = re_hierarchy_sep.exec(url_str); | |
url_part = url_str.substr(0, m.index); | |
url_str = url_str.substr(m.index); | |
// Auth | |
if ((m = re_auth.exec(url_part)) !== null) { | |
this.auth = m[1]; | |
url_part = url_part.substr(m[0].length); | |
} | |
else { | |
this.auth = null; | |
} | |
// Port | |
if ((m = re_port.exec(url_part)) !== null) { | |
this.port = parseInt(m[1], 10); | |
url_part = url_part.substr(0, m.index); | |
} | |
else { | |
this.port = null; | |
} | |
// Host name | |
url_part = url_part.toLowerCase(); | |
this.hostname = url_part; | |
this.host = url_part; | |
if (this.port !== null) { | |
this.host += ":"; | |
this.host += this.port; | |
} | |
} | |
else { | |
// Null | |
this.slashes = false; | |
this.host = null; | |
this.hostname = null; | |
this.auth = null; | |
this.port = null; | |
} | |
// Path | |
m = re_path_sep.exec(url_str); | |
this.pathname = url_str.substr(0, m.index); | |
if (this.pathname.length === 0 && this.slashes) { | |
this.pathname = "/"; | |
} | |
url_str = url_str.substr(m.index); | |
// Search | |
m = re_search_sep.exec(url_str); | |
this.search = url_str.substr(0, m.index); | |
url_str = url_str.substr(m.index); | |
// Fragment | |
this.hash = url_str; | |
// Done | |
return this; | |
}, | |
resolve: function (to) { | |
// Other parser | |
var other = new URLParser(to); | |
// Protocol | |
if (other.protocol === null) { | |
// Copy protocol | |
other.protocol = this.protocol; | |
} | |
// Hierarchy | |
if (!other.slashes && this.slashes) { | |
// Copy host | |
other.slashes = true; | |
other.host = this.host; | |
other.hostname = this.hostname; | |
other.auth = this.auth; | |
other.port = this.port; | |
} | |
// Path | |
if (other.pathname.length > 0) { | |
// Join paths | |
other.pathname = normalize_path(join_paths(this.pathname, other.pathname)); | |
} | |
else { | |
// Copy path | |
other.pathname = this.pathname; | |
// Search | |
if (other.search.length === 0) { | |
// Copy search | |
other.search = this.search; | |
// Hash | |
if (other.hash.length === 0) { | |
// Copy hash | |
other.hash = this.hash; | |
} | |
} | |
} | |
// Done | |
return other.join(); | |
}, | |
join: function () { | |
// Form | |
var url_str = ""; | |
if (this.protocol !== null) { | |
url_str += this.protocol; | |
} | |
if (this.slashes) { | |
url_str += "//"; | |
if (this.auth !== null) { | |
url_str += this.auth; | |
url_str += "@"; | |
} | |
url_str += this.hostname; | |
if (this.port !== null) { | |
url_str += ":"; | |
url_str += this.port; | |
} | |
} | |
url_str += this.pathname; | |
url_str += this.search; | |
url_str += this.hash; | |
return url_str; | |
}, | |
}; | |
// Functions | |
return URLParser; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment