# URI.js #
* [About](http://medialize.github.com/URI.js/)
* [Understanding URIs](http://medialize.github.com/URI.js/about-uris.html)
* [Documentation](http://medialize.github.com/URI.js/docs.html)
* [jQuery URI Plugin](http://medialize.github.com/URI.js/jquery-uri-plugin.html)
* [Author](http://rodneyrehm.de/en/)
---
I always want to shoot myself in the head when looking at code like the following:
```javascript
var url = "http://example.org/foo?bar=baz";
var separator = url.indexOf('?') > -1 ? '&' : '?';
url += separator + encodeURIComponent("foo") + "=" + encodeURIComponent("bar");
```
I still can't believe javascript - the f**ing backbone-language of the web - doesn't offer an API for mutating URLs. Browsers (Firefox) don't expose the `Location` object (the structure behind window.location). Yes, one could think of [decomposed IDL attributes](http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#url-decomposition-idl-attributes) as a native URL management library. But it relies on the DOM element <a>, it's slow and doesn't offer any convenience at all.
How about a nice, clean and simple API for mutating URIs:
```javascript
var url = new URI("http://example.org/foo?bar=baz");
url.addQuery("foo", "bar");
```
URI.js is here to help with that.
## API Example ##
```javascript
// mutating URLs
URI("http://example.org/foo.html?hello=world")
.username("rodneyrehm")
// -> http://rodneyrehm@example.org/foo.html?hello=world
.username("")
// -> http://example.org/foo.html?hello=world
.directory("bar")
// -> http://example.org/bar/foo.html?hello=world
.suffix("xml")
// -> http://example.org/bar/foo.xml?hello=world
.query("")
// -> http://example.org/bar/foo.xml
.tld("com")
// -> http://example.com/bar/foo.xml
.query({ foo: "bar", hello: ["world", "mars"] });
// -> http://example.com/bar/foo.xml?foo=bar&hello=world&hello=mars
// cleaning things up
URI("?&foo=bar&&foo=bar&foo=baz&")
.normalizeQuery();
// -> ?foo=bar&foo=baz
// working with relative paths
URI("/foo/bar/baz.html")
.relativeTo("/foo/bar/world.html");
// -> ./baz.html
URI("/foo/bar/baz.html")
.relativeTo("/foo/bar/sub/world.html")
// -> ../baz.html
.absoluteTo("/foo/bar/sub/world.html");
// -> /foo/bar/baz.html
// URI Templates
URI.expand("/foo/{dir}/{file}", {
dir: "bar",
file: "world.html"
});
// -> /foo/bar/world.html
```
See the [About Page](http://medialize.github.com/URI.js/) and [API Docs](http://medialize.github.com/URI.js/docs.html) for more stuff.
## Using URI.js ##
URI.js (without plugins) has a gzipped weight of about 7KB - if you include all extensions you end up at about 13KB. So unless you *need* second level domain support and use URI templates, we suggest you don't include them in your build. If you don't need a full featured URI mangler, it may be worth looking into the much smaller parser-only alternatives [listed below](#alternatives).
URI.js is available through [npm](http://npmjs.org/), [bower](http://bower.io/), [Jam](http://jamjs.org/) and manually from the [build page](http://medialize.github.io/URI.js/build.html):
```bash
# using bower
bower install uri.js
# using Jam
jam install URIjs
# using npm
npm install URIjs
```
### Browser ###
I guess you'll manage to use the [build tool](http://medialize.github.com/URI.js/build.html) or follow the [instructions below](#minify) to combine and minify the various files into URI.min.js - and I'm fairly certain you know how to `` that sucker, too.
### Node.js and NPM ###
Install with `npm install URIjs` or add `"URIjs"` to the dependencies in your `package.json`.
```javascript
// load URI.js
var URI = require('URIjs');
// load an optional module (e.g. URITemplate)
var URITemplate = require('URIjs/src/URITemplate');
URI("/foo/bar/baz.html")
.relativeTo("/foo/bar/sub/world.html")
// -> ../baz.html
```
### RequireJS ###
Clone the URI.js repository or use a package manager to get URI.js into your project.
```javascript
require.config({
paths: {
URIjs: 'where-you-put-uri.js/src'
}
});
require(['URIjs/URI'], function(URI) {
console.log("URI.js and dependencies: ", URI("//amazon.co.uk").is('sld') ? 'loaded' : 'failed');
});
require(['URIjs/URITemplate'], function(URITemplate) {
console.log("URITemplate.js and dependencies: ", URITemplate._cache ? 'loaded' : 'failed');
});
```
## Minify ##
See the [build tool](http://medialize.github.com/URI.js/build.html) or use [Google Closure Compiler](http://closure-compiler.appspot.com/home):
```
// ==ClosureCompiler==
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name URI.min.js
// @code_url http://medialize.github.com/URI.js/src/IPv6.js
// @code_url http://medialize.github.com/URI.js/src/punycode.js
// @code_url http://medialize.github.com/URI.js/src/SecondLevelDomains.js
// @code_url http://medialize.github.com/URI.js/src/URI.js
// @code_url http://medialize.github.com/URI.js/src/URITemplate.js
// ==/ClosureCompiler==
```
## Resources ##
Documents specifying how URLs work:
* [URL - Living Standard](http://url.spec.whatwg.org/)
* [RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax](http://tools.ietf.org/html/rfc3986)
* [RFC 3987 - Internationalized Resource Identifiers (IRI)](http://tools.ietf.org/html/rfc3987)
* [Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)](http://tools.ietf.org/html/rfc3492)
* [application/x-www-form-urlencoded](http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type) (Query String Parameters) and [application/x-www-form-urlencoded encoding algorithm](http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#application/x-www-form-urlencoded-encoding-algorithm)
Informal stuff
* [Parsing URLs for Fun and Profit](http://tools.ietf.org/html/draft-abarth-url-01)
* [Naming URL components](http://tantek.com/2011/238/b1/many-ways-slice-url-name-pieces)
How other environments do things
* [Java URI Class](http://docs.oracle.com/javase/7/docs/api/java/net/URI.html)
* [Java Inet6Address Class](http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Inet6Address.html)
* [Node.js URL API](http://nodejs.org/docs/latest/api/url.html)
[Discussion on Hacker News](https://news.ycombinator.com/item?id=3398837)
### Alternatives ###
If you don't like URI.js, you may like one of the following libraries. (If yours is not listed, drop me a lineā¦)
#### URL Manipulation ####
* [The simple URL Mutation "Hack"](http://jsfiddle.net/rodneyrehm/KkGUJ/) ([jsPerf comparison](http://jsperf.com/idl-attributes-vs-uri-js))
* [URL.js](https://github.com/ericf/urljs)
* [furl (Python)](https://github.com/gruns/furl)
* [mediawiki Uri](https://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/resources/mediawiki/mediawiki.Uri.js?view=markup) (needs mw and jQuery)
* [jurlp](https://github.com/tombonner/jurlp)
* [jsUri](http://code.google.com/p/jsuri/)
#### URL Parsers ####
* [The simple URL Mutation "Hack"](http://jsfiddle.net/rodneyrehm/KkGUJ/) ([jsPerf comparison](http://jsperf.com/idl-attributes-vs-uri-js))
* [URI Parser](http://blog.stevenlevithan.com/archives/parseuri)
* [jQuery-URL-Parser](https://github.com/allmarkedup/jQuery-URL-Parser)
* [Google Closure Uri](http://closure-library.googlecode.com/svn/docs/closure_goog_uri_uri.js.html)
* [URI.js by Gary Court](https://github.com/garycourt/uri-js)
#### URI Template ####
* [uri-templates](https://github.com/marc-portier/uri-templates) by Marc Portier
* [URI Template JS](https://github.com/fxa/uritemplate-js) by Franz Antesberger
* [Temple](https://github.com/brettstimmerman/temple) by Brett Stimmerman
* ([jsperf comparison](http://jsperf.com/uri-templates/2))
#### Various ####
* [TLD.js](https://github.com/oncletom/tld.js) - second level domain names
* [Public Suffix](http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1) - second level domain names
## Authors ##
* [Rodney Rehm](https://github.com/rodneyrehm)
* [Various Contributors](https://github.com/medialize/URI.js/graphs/contributors)
## Contains Code From ##
* [punycode.js](http://mths.be/punycode) - Mathias Bynens
* [IPv6.js](http://intermapper.com/support/tools/IPV6-Validator.aspx) - Rich Brown - (rewrite of the original)
## License ##
URI.js is published under the [MIT license](http://www.opensource.org/licenses/mit-license) and [GPL v3](http://opensource.org/licenses/GPL-3.0).
## Changelog ##
### 1.11.2 (August 14th 2013) ###
* fixing regression for Node.js introduced by `fixing unsafe eval by using UMD's root` - ([Issue #107](https://github.com/medialize/URI.js/issues/107))
* fixing parser to accept malformed userinfo (non-encoded email address) - ([Issue #108](https://github.com/medialize/URI.js/issues/108))
### 1.11.1 (August 13th 2013) ###
* fixing inconsistent [`.relativeTo()`](http://medialize.github.com/URI.js/docs.html#relativeto) results caused by inconsistent URI component handling - ([Issue #103](https://github.com/medialize/URI.js/issues/103))
* fixing unsafe eval by using UMD's root - ([Issue #105](https://github.com/medialize/URI.js/issues/105))
* fixing [`.segment()`](http://medialize.github.com/URI.js/docs.html#accessors-segment) to allow appending an empty element - ([Issue #106](https://github.com/medialize/URI.js/issues/106))
* fixing [`.segment()`](http://medialize.github.com/URI.js/docs.html#accessors-segment) to collapse empty elements in array notation
### 1.11.0 (August 6th 2013) ###
* adding [`.segmentCoded()`](http://medialize.github.com/URI.js/docs.html#accessors-segmentCoded) to provide en/decoding interface to `.segment()` - ([Issue #79](https://github.com/medialize/URI.js/issues/79))
* optimize [`.relativeTo()`](http://medialize.github.com/URI.js/docs.html#relativeto) results - ([Issue #78](https://github.com/medialize/URI.js/issues/78), [Issue #95](https://github.com/medialize/URI.js/issues/95))
* removing obsolete code fragments from `URI.parse()` and `relativeTo()` - ([Issue #100](https://github.com/medialize/URI.js/issues/100))
* adding setting [`URI.escapeQuerySpace`](http://medialize.github.io/URI.js/docs.html#setting-escapeQuerySpace) to control if query string should escape spaces using `+` or `%20` - ([Issue #74](https://github.com/medialize/URI.js/issues/74))
* updating [Punycode.js](https://github.com/bestiejs/punycode.js/) to version 1.2.3
* fixing internal `strictEncodeURIComponent()` to work in Firefox 3.6 - ([Issue #91](https://github.com/medialize/URI.js/issues/91))
* fixing [`.normalizePath()`](http://medialize.github.io/URI.js/docs.html#normalize-path) to properly resolve `/.` and `/.//` to `/` - ([Issue #97](https://github.com/medialize/URI.js/issues/97))
* fixing [`.path()`](http://medialize.github.io/URI.js/docs.html#accessors-pathname) to return empty string if there is no path - ([Issue #82](https://github.com/medialize/URI.js/issues/82))
* fixing crashing of `URI.decodeQuery()` on malformed input - now returns original undecoded data - ([Issue #87](https://github.com/medialize/URI.js/issues/87), [Issue #92](https://github.com/medialize/URI.js/issues/92))
* fixing build tool - ([Issue #83](https://github.com/medialize/URI.js/issues/83))
* fixing for-loop to make closure compiler happy - ([Issue #93](https://github.com/medialize/URI.js/issues/93))
* adding [`URI.noConflict()`](http://medialize.github.io/URI.js/docs.html#static-noConflict) - ([Issue #84](https://github.com/medialize/URI.js/issue/84))
* fixing whitespace in code - ([Issue #84](https://github.com/medialize/URI.js/issue/84))
* fixing [`.readable()`](http://medialize.github.com/URI.js/docs.html#readable) to decode the hash value as well - ([Issue #90](https://github.com/medialize/URI.js/issue/90))
* prevent `jquery.URI.js` from temporarily using `window.location` as the `href` of an empty attribute of a DOM element - ([Issue #94](https://github.com/medialize/URI.js/issues/94))
* fixing internal `getType()` for IE8 with undefined value - ([Issue #96](https://github.com/medialize/URI.js/issues/96))
* adding DOM elements to [URI constructor](http://medialize.github.io/URI.js/docs.html#constructor) - ([Issue #77](https://github.com/medialize/URI.js/issues/77)):
* [``](http://www.w3.org/html/wg/drafts/html/master/text-level-semantics.html#the-a-element)
* [``](http://www.w3.org/html/wg/drafts/html/master/grouping-content.html#the-blockquote-element)
* [``](http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-link-element)
* [``](http://www.w3.org/html/wg/drafts/html/master/document-metadata.html#the-base-element)
* [`