Last active
January 24, 2018 13:54
-
-
Save pieplu/6be55d1d8f27ea9b8dcf4de6b1933547 to your computer and use it in GitHub Desktop.
js-URI lib from https://code.google.com/archive/p/js-uri/
This file contains hidden or 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
/* | |
* An URI datatype. Based upon examples in RFC3986. | |
* | |
* TODO %-escaping | |
* TODO split apart authority | |
* TODO split apart query_string (on demand, anyway) | |
* | |
* @(#) $Id$ | |
*/ | |
// Constructor for the URI object. Parse a string into its components. | |
function URI(str) { | |
if (!str) str = ""; | |
// Based on the regex in RFC2396 Appendix B. | |
var parser = /^(?:([^:\/?\#]+):)?(?:\/\/([^\/?\#]*))?([^?\#]*)(?:\?([^\#]*))?(?:\#(.*))?/; | |
var result = str.match(parser); | |
this.scheme = result[1] || null; | |
this.authority = result[2] || null; | |
this.path = result[3] || null; | |
this.query = result[4] || null; | |
this.fragment = result[5] || null; | |
} | |
// Restore the URI to it's stringy glory. | |
URI.prototype.toString = function () { | |
var str = ""; | |
if (this.scheme) { | |
str += this.scheme + ":"; | |
} | |
if (this.authority) { | |
str += "//" + this.authority; | |
} | |
if (this.path) { | |
str += this.path; | |
} | |
if (this.query) { | |
str += "?" + this.query; | |
} | |
if (this.fragment) { | |
str += "#" + this.fragment; | |
} | |
return str; | |
}; | |
// Introduce a new scope to define some private helper functions. | |
(function () { | |
// RFC3986 §5.2.3 (Merge Paths) | |
function merge(base, rel_path) { | |
var dirname = /^(.*)\//; | |
if (base.authority && !base.path) { | |
return "/" + rel_path; | |
} | |
else { | |
return base.path.match(dirname)[0] + rel_path; | |
} | |
} | |
// Match two path segments, where the second is ".." and the first must | |
// not be "..". | |
var DoubleDot = /\/((?!\.\.\/)[^\/]*)\/\.\.\//; | |
function remove_dot_segments(path) { | |
if (!path) return ""; | |
// Remove any single dots | |
var newpath = path.replace(/\/\.\//g, '/'); | |
// Remove any trailing single dots. | |
newpath = newpath.replace(/\/\.$/, '/'); | |
// Remove any double dots and the path previous. NB: We can't use | |
// the "g", modifier because we are changing the string that we're | |
// matching over. | |
while (newpath.match(DoubleDot)) { | |
newpath = newpath.replace(DoubleDot, '/'); | |
} | |
// Remove any trailing double dots. | |
newpath = newpath.replace(/\/([^\/]*)\/\.\.$/, '/'); | |
// If there are any remaining double dot bits, then they're wrong | |
// and must be nuked. Again, we can't use the g modifier. | |
while (newpath.match(/\/\.\.\//)) { | |
newpath = newpath.replace(/\/\.\.\//, '/'); | |
} | |
return newpath; | |
} | |
// RFC3986 §5.2.2. Transform References; | |
URI.prototype.resolve = function (base) { | |
var target = new URI(); | |
if (this.scheme) { | |
target.scheme = this.scheme; | |
target.authority = this.authority; | |
target.path = remove_dot_segments(this.path); | |
target.query = this.query; | |
} | |
else { | |
if (this.authority) { | |
target.authority = this.authority; | |
target.path = remove_dot_segments(this.path); | |
target.query = this.query; | |
} | |
else { | |
// XXX Original spec says "if defined and empty"…; | |
if (!this.path) { | |
target.path = base.path; | |
if (this.query) { | |
target.query = this.query; | |
} | |
else { | |
target.query = base.query; | |
} | |
} | |
else { | |
if (this.path.charAt(0) === '/') { | |
target.path = remove_dot_segments(this.path); | |
} else { | |
target.path = merge(base, this.path); | |
target.path = remove_dot_segments(target.path); | |
} | |
target.query = this.query; | |
} | |
target.authority = base.authority; | |
} | |
target.scheme = base.scheme; | |
} | |
target.fragment = this.fragment; | |
return target; | |
}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment