Last active
December 16, 2015 13:39
-
-
Save termi/5443716 to your computer and use it in GitHub Desktop.
JavaScript + DOM implementation of http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html
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
void function() { | |
"use strict"; | |
var global = this; | |
//Mini alternative https://gist.github.com/2428561 | |
//Uses | |
//https://gist.github.com/1384398 | |
//https://gist.github.com/1235332 | |
function parseSearch(s, match, notMatch, valueOnly, nameOnly) { | |
var result = [] | |
, parts = s.slice(1).split('&') | |
, i = 0 | |
, part | |
, key | |
, value | |
; | |
for( ; i < parts.length; i++ ) { | |
part = parts[i]; | |
key = part.split('=', 1)[0]; | |
if( key && (match == void 0 || match == key) && (notMatch == void 0 || notMatch != key) ) { | |
value = part.slice(key.length + 1); | |
result.push(valueOnly ? value : nameOnly ? key : [key, value]); | |
} | |
} | |
return result; | |
} | |
function serializeParsed(array) { | |
var i = 0 | |
, l = array.length | |
, result = [] | |
, pair | |
; | |
for( ; i < l ; ++i ) { | |
pair = array[i]; | |
result[i] = pair[1] !== '' ? pair.join('=') : pair[0]; | |
} | |
return result.join('&'); | |
} | |
function _URL(url, base) { | |
if( this === global || this === null ) { | |
throw new TypeError("DOM object constructor cannot be called as a function"); | |
} | |
if( !url ) | |
throw new TypeError('Invalid argument'); | |
var thisObj = this | |
//https://gist.github.com/1235332 | |
, m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/) | |
; | |
thisObj.href = m[0]; | |
if( thisObj.href === '' ) { | |
throw new TypeError('Invalid URL'); | |
} | |
thisObj.protocol = m[1] || ""; | |
thisObj.authority = m[2] || ""; | |
thisObj.host = m[3] || ""; | |
thisObj.hostname = m[4] || ""; | |
thisObj.port = m[5] || ""; | |
thisObj.pathname = m[6] || ""; | |
thisObj.search = m[7] || ""; | |
thisObj.hash = m[8] || ""; | |
var match; | |
if( (match = thisObj.pathname.match(/\/([^\/]+)$/)) ) { | |
thisObj.filename = match[1]; | |
} | |
thisObj.filename = ''; | |
thisObj.parameterNames = Object.create ? Object.create(null) : {}; | |
var searchArray = parseSearch(thisObj.search, void 0, void 0, void 0, true) | |
, i = 0 | |
, l = searchArray.length | |
, result = [] | |
, name | |
; | |
for( ; i < l ; ++i ) { | |
name = searchArray[i]; | |
if( !(name in thisObj.parameterNames) ) { | |
thisObj.parameterNames[name] = true; | |
result.push(name); | |
} | |
} | |
} | |
_URL.prototype = { | |
toString: function() { | |
return this.href; | |
}, | |
// 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; | |
// }, | |
getParameter: function(name) { | |
return this.getParameterAll(name).pop(); | |
}, | |
getParameterAll: function(name) { | |
return parseSearch(this.search, name + "", void 0, true); | |
}, | |
appendParameter: function(name, values) { | |
this.parameterNames[name] = true; | |
if( !Array.isArray(values) ) { | |
values = [values]; | |
} | |
var parsed = parseSearch(this.search); | |
for( var i = 0; i < values.length; i++ ) { | |
parsed.push([name, values[i]]); | |
} | |
parsed = serializeParsed(parsed); | |
this.search = parsed ? ("?" + parsed) : ""; | |
_recalculateHref.call(this); | |
}, | |
clearParameter: function(name) { | |
if( name in this.parameterNames ) { | |
delete this.parameterNames[name]; | |
} | |
name = serializeParsed( | |
parseSearch(this.search, void 0, name) | |
); | |
this.search = name ? ("?" + name) : ""; | |
_recalculateHref.call(this); | |
} | |
}; | |
function _recalculateHref() { | |
this.href = this.protocol + "//" + this.host + this.pathname + this.search; | |
} | |
var oldURL; | |
if( oldURL = global.URL || global.webkitURL || global.mozURL ) { | |
if( oldURL.createObjectURL ) { | |
_URL.createObjectURL = function(blob) { | |
return this.createObjectURL.apply(this, arguments); | |
}.bind(oldURL); | |
} | |
if( oldURL.revokeObjectURL ) { | |
_URL.revokeObjectURL = function(url) { | |
return this.revokeObjectURL.apply(this, arguments); | |
}.bind(oldURL); | |
} | |
} | |
oldURL = null; | |
/* | |
// 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});*/ | |
//EXPORT | |
global["URL"] = _URL; | |
}.call(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment