- 
      
- 
        Save arv/1384398 to your computer and use it in GitHub Desktop. 
| <!DOCTYPE html> | |
| <script src="url.js"></script> | |
| <script> | |
| var url = new URL('http://www.example.com/a/b/c.html?p=q&r=s&p&p=t#hash'); | |
| for (var key in url) { | |
| console.log(key, url[key]); | |
| } | |
| </script> | 
| var URL = (function() { | |
| function parseSearch(s) { | |
| var result = []; | |
| var k = 0; | |
| var parts = s.slice(1).split('&'); | |
| for (var i = 0; i < parts.length; i++) { | |
| var part = parts[i]; | |
| var key = part.split('=', 1)[0]; | |
| if (key) { | |
| var value = part.slice(key.length + 1); | |
| result[k++] = [key, value]; | |
| } | |
| } | |
| return result; | |
| } | |
| function serializeParsed(array) { | |
| return array.map(function(pair) { | |
| return pair[1] !== '' ? pair.join('=') : pair[0]; | |
| }).join('&'); | |
| } | |
| function URL(url, base) { | |
| if (!url) | |
| throw new TypeError('Invalid argument'); | |
| var doc = document.implementation.createHTMLDocument(''); | |
| if (base) { | |
| var baseElement = doc.createElement('base'); | |
| baseElement.href = base || window.lo; | |
| doc.head.appendChild(baseElement); | |
| } | |
| var anchorElement = doc.createElement('a'); | |
| anchorElement.href = url; | |
| doc.body.appendChild(anchorElement); | |
| if (anchorElement.href === '') | |
| throw new TypeError('Invalid URL'); | |
| Object.defineProperty(this, '_anchorElement', {value: anchorElement}); | |
| } | |
| URL.prototype = { | |
| toString: function() { | |
| return this.href; | |
| }, | |
| get href() { | |
| return this._anchorElement.href; | |
| }, | |
| set href(value) { | |
| this._anchorElement.href = value; | |
| }, | |
| get protocol() { | |
| return this._anchorElement.protocol; | |
| }, | |
| set protocol(value) { | |
| this._anchorElement.protocol = value; | |
| }, | |
| // NOT IMPLEMENTED | |
| // get username() { | |
| // return this._anchorElement.username; | |
| // }, | |
| // set username(value) { | |
| // this._anchorElement.username = value; | |
| // }, | |
| // get password() { | |
| // return this._anchorElement.password; | |
| // }, | |
| // set password(value) { | |
| // this._anchorElement.password = value; | |
| // }, | |
| // get origin() { | |
| // return this._anchorElement.origin; | |
| // }, | |
| get host() { | |
| return this._anchorElement.host; | |
| }, | |
| set host(value) { | |
| this._anchorElement.host = value; | |
| }, | |
| get hostname() { | |
| return this._anchorElement.hostname; | |
| }, | |
| set hostname(value) { | |
| this._anchorElement.hostname = value; | |
| }, | |
| get port() { | |
| return this._anchorElement.port; | |
| }, | |
| set port(value) { | |
| this._anchorElement.port = value; | |
| }, | |
| get pathname() { | |
| return this._anchorElement.pathname; | |
| }, | |
| set pathname(value) { | |
| this._anchorElement.pathname = value; | |
| }, | |
| get search() { | |
| return this._anchorElement.search; | |
| }, | |
| set search(value) { | |
| this._anchorElement.search = value; | |
| }, | |
| get hash() { | |
| return this._anchorElement.hash; | |
| }, | |
| set hash(value) { | |
| this._anchorElement.hash = value; | |
| }, | |
| get filename() { | |
| var match; | |
| if ((match = this.pathname.match(/\/([^\/]+)$/))) | |
| return match[1]; | |
| return ''; | |
| }, | |
| set filename(value) { | |
| var match, pathname = this.pathname; | |
| if ((match = pathname.match(/\/([^\/]+)$/))) | |
| this.pathname = pathname.slice(0, -match[1].length) + value; | |
| else | |
| this.pathname = value; | |
| }, | |
| get parameterNames() { | |
| var seen = Object.create(null); | |
| return parseSearch(this.search).map(function(pair) { | |
| return pair[0]; | |
| }).filter(function(key) { | |
| if (key in seen) | |
| return false; | |
| seen[key] = true; | |
| return true; | |
| }); | |
| }, | |
| getParameter: function(name) { | |
| return this.getParameterAll(name).pop(); | |
| }, | |
| getParameterAll: function(name) { | |
| name = String(name); | |
| var result = []; | |
| var k = 0; | |
| parseSearch(this.search).forEach(function(pair) { | |
| if (pair[0] === name) | |
| result[k++] = pair[1]; | |
| }); | |
| return result; | |
| }, | |
| appendParameter: function(name, values) { | |
| if (!Array.isArray(values)) | |
| values = [values]; | |
| var parsed = parseSearch(this.search); | |
| for (var i = 0; i < values.length; i++) { | |
| parsed.push([name, values[i]]); | |
| } | |
| this.search = serializeParsed(parsed); | |
| }, | |
| clearParameter: function(name) { | |
| this.search = serializeParsed( | |
| parseSearch(this.search).filter(function(pair) { | |
| return pair[0] !== name; | |
| })); | |
| }, | |
| }; | |
| var oldURL = window.URL || window.webkitURL || window.mozURL; | |
| URL.createObjectURL = function(blob) { | |
| return oldURL.createObjectURL.apply(oldURL, arguments); | |
| }; | |
| URL.revokeObjectURL = function(url) { | |
| return oldURL.revokeObjectURL.apply(oldURL, arguments); | |
| }; | |
| // Methods should not be enumerable. | |
| Object.defineProperty(URL.prototype, 'toString', {enumerable: false}); | |
| Object.defineProperty(URL.prototype, 'getParameter', {enumerable: false}); | |
| Object.defineProperty(URL.prototype, 'getParameterAll', {enumerable: false}); | |
| Object.defineProperty(URL.prototype, 'appendParameter', {enumerable: false}); | |
| Object.defineProperty(URL.prototype, 'clearParameter', {enumerable: false}); | |
| Object.defineProperty(URL, 'createObjectURL', {enumerable: false}); | |
| Object.defineProperty(URL, 'revokeObjectURL', {enumerable: false}); | |
| return URL; | |
| })(); | 
Hello, guys!
i have  this code https://gist.github.com/1235332 for URL resolving, may be it's better to include this and not use DOM ?
Without DOM this script will work under node.js and WebWorkers and performnace will be increased.
This gist was created in response to https://bugs.webkit.org/show_bug.cgi?id=71968 which is about adding a URL host object to WebKit.
Implementing a correct URL object in JS requires thousands of lines of code that needs to be downloaded over and over. All browsers already ship with C++ implementations of URLs already so we want to leverage this.
@arv, the algorithm is described at the spec. - https://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#concept-url-parser
do not think it requires thousands of lines of code
I think you need to use
window.URLfor modern Firefox.window.mozURLisundefinedin Firefox Nightly 11.