|
/** |
|
* A URL parser written in JavaScript. |
|
* Copyright (C) 2015 Ryan Kane |
|
* |
|
* This program is free software: you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation, either version 3 of the License, or |
|
* (at your option) any later version. |
|
|
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
*/ |
|
var URLParser = (function(document) { |
|
var COMPONENTS = 'protocol host hostname port pathname search hash href'.split(' '); |
|
var PROPS = COMPONENTS.concat('port requestUri parameters'.split(' ')); |
|
var URI_PATTERN = /^((?:ht|f)tp(?:s?)?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)(\/[^?#]*)(\?[^#]*|)(#.*|)$/; |
|
var prependIf = function(value, char) { |
|
return value.indexOf(char) !== 0 ? char + value : value; |
|
}; |
|
var parseParamVal = function(value) { |
|
if (value.match(/^-?\d+$/)) { |
|
return parseInt(value, 10); |
|
} else if (value.match(/^-?\d+\.\d+$/)) { |
|
return parseFloat(value); |
|
} |
|
return value; |
|
}; |
|
var parseParams = function(query) { |
|
query = query.substring(1) || ''; |
|
var params = {}; |
|
var pairs = query.split('&'); |
|
if (pairs[0].length > 1) { |
|
pairs.forEach(function(pair) { |
|
var param = pair.split("="); |
|
var key = decodeURI(param[0]); |
|
var val = parseParamVal(decodeURI(param[1])); |
|
if (params[key] === undefined) { |
|
params[key] = val; |
|
} else if (typeof params[key] === "string") { |
|
params[key] = [params[key], val]; |
|
} else { |
|
params[key].push(val); |
|
} |
|
}, this); |
|
} |
|
return params; |
|
}; |
|
var self = function(debug) { |
|
this.debug = debug; |
|
this.domExists = document !== undefined; |
|
if (this.domExists) { |
|
this.aEl = document.createElement('a'); |
|
} |
|
}; |
|
self.prototype.parse = function(url) { |
|
var success = false; |
|
if (this.domExists && !this.debug) { |
|
this.aEl.href = url; |
|
if (this.aEl.host == "") { |
|
this.aEl.href = this.aEl.href; |
|
} |
|
COMPONENTS.forEach(function(prop) { |
|
this[prop] = this.aEl[prop]; |
|
}, this); |
|
success = true; |
|
} else { |
|
var match = url.match(URI_PATTERN); |
|
if (match) { |
|
COMPONENTS.forEach(function(component, index) { |
|
this[component] = match[index + 1] || ''; |
|
}, this); |
|
success = true; |
|
} |
|
} |
|
if (success) { |
|
this.href = url; |
|
this.hash = this.hash.substr(1); |
|
this.pathname = prependIf(this.pathname, '/'); |
|
this.requestUri = this.pathname + this.search; |
|
this.parameters = parseParams(this.search); |
|
} |
|
return this.toObj(); |
|
}; |
|
self.prototype.toObj = function() { |
|
var obj = {}; |
|
PROPS.forEach(function(prop) { |
|
obj[prop] = this[prop]; |
|
}, this); |
|
return obj; |
|
}; |
|
self.prototype.toString = function() { |
|
return this.href; |
|
}; |
|
return self; |
|
})(document); |