Javascript URL Library code
/**
* Copyright 2009 Michael Little, Christian Biggins
*
* 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 .
*/
if (typeof FLQ == 'undefined') var FLQ = function () { }
/**
* FLQ.URL - Fliquid URL building/handling class
*
* Version: 1.0.0 BETA
*/
FLQ.URL = function (url) {
this.scheme = null;
this.host = null;
this.port = null;
this.path = null;
this.args = {};
this.anchor = null;
if (arguments.length > 0) this.set(url);
}
/**
* thisURL() parses the current window.location and returns a FLQ.URL object
*/
FLQ.URL.thisURL = function () {
return new FLQ.URL(window.location.href);
}
FLQ.URL.prototype = new Object();
/**
* set() parses a url and sets the properties of the FLQ.URL object
*/
FLQ.URL.prototype.set = function (url) {
var p;
if (p = this.parseURL(url)) {
this.scheme = p['scheme'];
this.host = p['host'];
this.port = p['port'];
this.path = p['path'];
this.args = this.parseArgs(p['args']);
this.anchor = p['anchor'];
}
}
/**
* removeArg() is used remove a specified argument from the FLQ.URL object arguments
*/
FLQ.URL.prototype.removeArg = function (k) {
if (k && String(k.constructor) == String(Array)) { // TODO: Change to use is_array
var t = this.args;
for (var i=0; i < k.length-1; i++) {
if (typeof t[k[i]] != 'undefined') { // TODO: Change to use isset
t = t[k[i]];
} else {
return false;
}
}
delete t[k[k.length-1]];
return true;
} else if (typeof this.args[k] != 'undefined') { // TODO: Change to use isset
delete this.args[k];
return true;
}
return false;
}
/**
* addArg() is used to add an argument with specified value to the FLQ.URL object arguments
*/
FLQ.URL.prototype.addArg = function (k, v, o) {
if (k && String(k.constructor) == String(Array)) { // TODO: Change to use is_array
var t = this.args;
for (var i=0; i < k.length-1; i++) {
if (typeof t[k[i]] == 'undefined') t[k[i]] = {};
t = t[k[i]];
}
if (o || typeof t[k[k.length-1]] == 'undefined') t[k[k.length-1]] = v; // TODO: Change to use isset
} else if (o || typeof this.args[k] == 'undefined') { // TODO: Change to use isset
this.args[k] = v;
return true;
}
return false;
}
/**
* parseURL() parses the specified url and returns an object containing the various components
*/
FLQ.URL.prototype.parseURL = function (url) {
// TODO: Add support for ftp username
var p = {}, m;
if (m = url.match(/((s?ftp|https?):\/\/)?([^\/:]+)?(:([0-9]+))?([^\?#]+)?(\?([^#]+))?(#(.+))?/)) {
p['scheme'] = (m[2] ? m[2] : 'http');
p['host'] = (m[3] ? m[3] : window.location.host);
p['port'] = (m[5] ? m[5] : null);
p['path'] = (m[6] ? m[6] : null);
p['args'] = (m[8] ? m[8] : null);
p['anchor'] = (m[10] ? m[10] : null);
return p;
}
return false;
}
/**
* parseArgs() parses a query string and returns an object containing the parsed data
*/
FLQ.URL.prototype.parseArgs = function (s) {
var a = {};
if (s && s.length) {
var kp, kv;
var p;
if ((kp = s.split('&')) && kp.length) {
for (var i=0; i < kp.length; i++) {
if ((kv = kp[i].split('=')) && kv.length == 2) {
if (p = kv[0].split(/(\[|\]\[|\])/)) {
for (var z=0; z < p.length; z++) {
if (p[z] == ']' || p[z] == '[' || p[z] == '][') {
p.splice(z, 1);
}
}
var t = a;
for (var o=0; o < p.length-1; o++) {
if (typeof t[p[o]] == 'undefined') t[p[o]] = {}; // TODO: Change this to isset
t = t[p[o]];
}
t[p[p.length-1]] = kv[1];
} else {
a[kv[0]] = kv[1];
}
}
}
}
}
return a;
}
/**
* toArgs() takes an object and returns a query string
*/
FLQ.URL.prototype.toArgs = function (a, p) {
if (arguments.length < 2) p = '';
if (a && typeof a == 'object') { // TODO: Change this to use is_object
var s = '';
for (i in a) {
if (typeof a[i] != 'function') {
if (s.length) s+= '&';
if (typeof a[i] == 'object') { // TODO: Change this to use is_object
var k = (p.length ? p+'['+i+']' : i);
s+= this.toArgs(a[i], k);
} else { // TODO: Change this to use is_function
s+= p+(p.length && i != '' ? '[' : '')+i+(p.length && i != '' ? ']' : '')+'='+a[i];
}
}
}
return s;
}
return '';
}
/**
* toAbsolute() returns a string containing the absolute URL for the current FLQ.URL object
*/
FLQ.URL.prototype.toAbsolute = function () {
var s = '';
if (this.scheme != null) s+= this.scheme+'://';
if (this.host != null) s+= this.host;
if (this.port != null) s+= ':'+this.port;
s+= this.toRelative();
return s;
}
/**
* toRelative() returns a string containing the relative URL for the current FLQ.URL object
*/
FLQ.URL.prototype.toRelative = function () {
var s = '';
if (this.path != null) s+= this.path;
var a = this.toArgs(this.args);
if (a.length) s+= '?'+a;
if (this.anchor != null) s+= '#'+this.anchor;
return s;
}
/**
* isHost() is used to determine whether the host in the FLQ.URL object matches the current host
*/
FLQ.URL.prototype.isHost = function () {
var u = FLQ.URL.thisURL();
return (this.host == null || this.host == u.host ? true : false);
}
/**
* toString() returns a string containing the current FLQ.URL object as a URL
*/
FLQ.URL.prototype.toString = function () {
return (this.isHost() ? this.toRelative() : this.toAbsolute());
}
