Skip to content

Commit

Permalink
Merge pull request #57 from juliangruber/compat
Browse files Browse the repository at this point in the history
browser compatibility
  • Loading branch information
tj committed Apr 23, 2013
2 parents db8726e + e0ee42f commit 2640fab
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 64 deletions.
104 changes: 77 additions & 27 deletions index.js
Expand Up @@ -5,6 +5,58 @@


var toString = Object.prototype.toString; var toString = Object.prototype.toString;


/**
* Array#indexOf shim.
*/

var indexOf = typeof Array.prototype.indexOf === 'function'
? function(arr, el) { return arr.indexOf(el); }
: function(arr, el) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === el) return i;
}
return -1;
};

/**
* Array.isArray shim.
*/

var isArray = Array.isArray || function(arr) {
return toString.call(arr) == '[object Array]';
};

/**
* Object.keys shim.
*/

var objectKeys = Object.keys || function(obj) {
var ret = [];
for (var key in obj) ret.push(key);
return ret;
};

/**
* Array#forEach shim.
*/

var forEach = typeof Array.prototype.forEach === 'function'
? function(arr, fn) { return arr.forEach(fn); }
: function(arr, fn) {
for (var i = 0; i < arr.length; i++) fn(arr[i]);
};

/**
* Array#reduce shim.
*/

var reduce = function(arr, fn, initial) {
if (typeof arr.reduce === 'function') return arr.reduce(fn, initial);
var res = initial;
for (var i = 0; i < arr.length; i++) res = fn(res, arr[i]);
return res;
};

/** /**
* Cache non-integer test regexp. * Cache non-integer test regexp.
*/ */
Expand All @@ -23,7 +75,7 @@ function parse(parts, parent, key, val) {
var part = parts.shift(); var part = parts.shift();
// end // end
if (!part) { if (!part) {
if (Array.isArray(parent[key])) { if (isArray(parent[key])) {
parent[key].push(val); parent[key].push(val);
} else if ('object' == typeof parent[key]) { } else if ('object' == typeof parent[key]) {
parent[key] = val; parent[key] = val;
Expand All @@ -36,21 +88,21 @@ function parse(parts, parent, key, val) {
} else { } else {
var obj = parent[key] = parent[key] || []; var obj = parent[key] = parent[key] || [];
if (']' == part) { if (']' == part) {
if (Array.isArray(obj)) { if (isArray(obj)) {
if ('' != val) obj.push(val); if ('' != val) obj.push(val);
} else if ('object' == typeof obj) { } else if ('object' == typeof obj) {
obj[Object.keys(obj).length] = val; obj[objectKeys(obj).length] = val;
} else { } else {
obj = parent[key] = [parent[key], val]; obj = parent[key] = [parent[key], val];
} }
// prop // prop
} else if (~part.indexOf(']')) { } else if (~indexOf(part, ']')) {
part = part.substr(0, part.length - 1); part = part.substr(0, part.length - 1);
if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
parse(parts, obj, part, val); parse(parts, obj, part, val);
// key // key
} else { } else {
if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key); if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
parse(parts, obj, part, val); parse(parts, obj, part, val);
} }
} }
Expand All @@ -61,14 +113,14 @@ function parse(parts, parent, key, val) {
*/ */


function merge(parent, key, val){ function merge(parent, key, val){
if (~key.indexOf(']')) { if (~indexOf(key, ']')) {
var parts = key.split('[') var parts = key.split('[')
, len = parts.length , len = parts.length
, last = len - 1; , last = len - 1;
parse(parts, parent, 'base', val); parse(parts, parent, 'base', val);
// optimize // optimize
} else { } else {
if (!isint.test(key) && Array.isArray(parent.base)) { if (!isint.test(key) && isArray(parent.base)) {
var t = {}; var t = {};
for (var k in parent.base) t[k] = parent.base[k]; for (var k in parent.base) t[k] = parent.base[k];
parent.base = t; parent.base = t;
Expand All @@ -85,7 +137,7 @@ function merge(parent, key, val){


function parseObject(obj){ function parseObject(obj){
var ret = { base: {} }; var ret = { base: {} };
Object.keys(obj).forEach(function(name){ forEach(objectKeys(obj), function(name){
merge(ret, name, obj[name]); merge(ret, name, obj[name]);
}); });
return ret.base; return ret.base;
Expand All @@ -96,21 +148,19 @@ function parseObject(obj){
*/ */


function parseString(str){ function parseString(str){
return String(str) return reduce(String(str).split('&'), function(ret, pair){
.split('&') var eql = indexOf(pair, '=')
.reduce(function(ret, pair){ , brace = lastBraceInKey(pair)
var eql = pair.indexOf('=') , key = pair.substr(0, brace || eql)
, brace = lastBraceInKey(pair) , val = pair.substr(brace || eql, pair.length)
, key = pair.substr(0, brace || eql) , val = val.substr(indexOf(val, '=') + 1, val.length);
, val = pair.substr(brace || eql, pair.length)
, val = val.substr(val.indexOf('=') + 1, val.length); // ?foo

if ('' == key) key = pair, val = '';
// ?foo if ('' == key) return ret;
if ('' == key) key = pair, val = '';
if ('' == key) return ret; return merge(ret, decode(key), decode(val));

}, { base: {} }).base;
return merge(ret, decode(key), decode(val));
}, { base: {} }).base;
} }


/** /**
Expand All @@ -137,7 +187,7 @@ exports.parse = function(str){
*/ */


var stringify = exports.stringify = function(obj, prefix) { var stringify = exports.stringify = function(obj, prefix) {
if (Array.isArray(obj)) { if (isArray(obj)) {
return stringifyArray(obj, prefix); return stringifyArray(obj, prefix);
} else if ('[object Object]' == toString.call(obj)) { } else if ('[object Object]' == toString.call(obj)) {
return stringifyObject(obj, prefix); return stringifyObject(obj, prefix);
Expand Down Expand Up @@ -191,7 +241,7 @@ function stringifyArray(arr, prefix) {


function stringifyObject(obj, prefix) { function stringifyObject(obj, prefix) {
var ret = [] var ret = []
, keys = Object.keys(obj) , keys = objectKeys(obj)
, key; , key;


for (var i = 0, len = keys.length; i < len; ++i) { for (var i = 0, len = keys.length; i < len; ++i) {
Expand Down Expand Up @@ -223,7 +273,7 @@ function set(obj, key, val) {
var v = obj[key]; var v = obj[key];
if (undefined === v) { if (undefined === v) {
obj[key] = val; obj[key] = val;
} else if (Array.isArray(v)) { } else if (isArray(v)) {
v.push(val); v.push(val);
} else { } else {
obj[key] = [v, val]; obj[key] = [v, val];
Expand Down

0 comments on commit 2640fab

Please sign in to comment.