ifui
Version:
156 lines (135 loc) • 4.04 kB
JavaScript
// QueryString
// ---------------
// This module provides utilities for dealing with query strings.
//
// Thanks to:
// - http://nodejs.org/docs/v0.4.7/api/querystring.html
// - http://developer.yahoo.com/yui/3/api/QueryString.html
// - https://github.com/lifesinger/dew/tree/master/lib/querystring
var QueryString = exports
// The escape/unescape function used by stringify/parse, provided so that it
// could be overridden if necessary. This is important in cases where
// non-standard delimiters are used, if the delimiters would not normally be
// handled properly by the built-in (en|de)codeURIComponent functions.
QueryString.escape = encodeURIComponent
QueryString.unescape = function (s) {
// The + character is interpreted as a space on the server side as well as
// generated by forms with spaces in their fields.
return decodeURIComponent(s.replace(/\+/g, ' '))
}
/**
* Serialize an object to a query string. Optionally override the default
* separator and assignment characters.
*
* stringify({foo: 'bar'})
* // returns 'foo=bar'
*
* stringify({foo: 'bar', baz: 'bob'}, ';', ':')
* // returns 'foo:bar;baz:bob'
*/
QueryString.stringify = function (obj, sep, eq, arrayKey) {
if (!isPlainObject(obj)) return ''
sep = sep || '&'
eq = eq || '='
arrayKey = arrayKey || false
var buf = []
var val = ''
var escape = QueryString.escape
for (var key in obj) {
if (!hasOwnProperty.call(obj, key)) continue
val = obj[key]
key = QueryString.escape(key)
// val is primitive value
if (isPrimitive(val)) {
buf.push(key, eq, escape(val + ''), sep)
} else if (isArray(val) && val.length) {
for (var i = 0; i < val.length; i++) {
if (isPrimitive(val[i])) {
buf.push(
key,
(arrayKey ? escape('[]') : '') + eq,
escape(val[i] + ''),
sep)
}
}
} else {
buf.push(key, eq, sep)
}
}
buf.pop()
return buf.join('')
}
/**
* Deserialize a query string to an object. Optionally override the default
* separator and assignment characters.
*
* parse('a=b&c=d')
* // returns {a: 'b', c: 'c'}
*/
QueryString.parse = function (str, sep, eq) {
if (typeof str === 'undefined') {
str = document.location.search
}
var ret = {}
if (typeof str !== 'string' || trim(str).length === 0) {
return ret
}
// remove ^?
str = str.replace(/^\?/, '')
var pairs = str.split(sep || '&')
eq = eq || '='
var unescape = QueryString.unescape
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].split(eq)
var key = unescape(trim(pair[0]))
var val = unescape(trim(pair.slice(1).join(eq)))
var m = key.match(/^(\w+)\[\]$/)
if (m && m[1]) {
key = m[1]
}
if (hasOwnProperty.call(ret, key)) {
if (!isArray(ret[key])) {
ret[key] = [ret[key]]
}
ret[key].push(val)
} else {
ret[key] = m ? [val] : val
}
}
return ret
}
// Helpers
var toString = Object.prototype.toString
var hasOwnProperty = Object.prototype.hasOwnProperty
var isArray = Array.isArray || function (val) {
return toString.call(val) === '[object Array]'
}
var trim = String.prototype.trim ? function (str) {
return (str == null) ? '' : String.prototype.trim.call(str)
} : function (str) {
return (str == null) ? '' : str.toString().replace(/^\s+/, '').replace(/\s+$/, '')
}
/**
* Checks to see if an object is a plain object (created using "{}" or
* "new Object()" or "new FunctionClass()").
*/
function isPlainObject (o) {
/**
* NOTES:
* isPlainObject(node = document.getElementById("xx")) -> false
* toString.call(node):
* ie678 === '[object Object]', other === '[object HTMLElement]'
* 'isPrototypeOf' in node:
* ie678 === false, other === true
*/
return o &&
toString.call(o) === '[object Object]' &&
'isPrototypeOf' in o
}
/**
* If the type of o is null, undefined, number, string, boolean,
* return true.
*/
function isPrimitive (o) {
return o !== Object(o)
}