-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathjquery-deparam.js
122 lines (107 loc) · 4.92 KB
/
jquery-deparam.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
(function(deparam){
if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
try {
var jquery = require('jquery');
} catch (e) {
}
module.exports = deparam(jquery);
} else if (typeof define === 'function' && define.amd){
define(['jquery'], function(jquery){
return deparam(jquery);
});
} else {
var global;
try {
global = (false || eval)('this'); // best cross-browser way to determine global for < ES5
} catch (e) {
global = window; // fails only if browser (https://developer.mozilla.org/en-US/docs/Web/Security/CSP/CSP_policy_directives)
}
global.deparam = deparam(global.jQuery); // assume jQuery is in global namespace
}
})(function ($) {
var deparam = function( params, coerce ) {
var obj = {},
coerce_types = { 'true': !0, 'false': !1, 'null': null };
// If params is an empty string or otherwise falsy, return obj.
if (!params) {
return obj;
}
// Iterate over all name=value pairs.
params.replace(/\+/g, ' ').split('&').forEach(function(v){
var param = v.split( '=' ),
key = decodeURIComponent( param[0] ),
val,
cur = obj,
i = 0,
// If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
// into its component parts.
keys = key.split( '][' ),
keys_last = keys.length - 1;
// If the first keys part contains [ and the last ends with ], then []
// are correctly balanced.
if ( /\[/.test( keys[0] ) && /\]$/.test( keys[ keys_last ] ) ) {
// Remove the trailing ] from the last keys part.
keys[ keys_last ] = keys[ keys_last ].replace( /\]$/, '' );
// Split first keys part into two parts on the [ and add them back onto
// the beginning of the keys array.
keys = keys.shift().split('[').concat( keys );
keys_last = keys.length - 1;
} else {
// Basic 'foo' style key.
keys_last = 0;
}
// Are we dealing with a name=value pair, or just a name?
if ( param.length === 2 ) {
val = decodeURIComponent( param[1] );
// Coerce values.
if ( coerce ) {
val = val && !isNaN(val) && ((+val + '') === val) ? +val // number
: val === 'undefined' ? undefined // undefined
: coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
: val; // string
}
if ( keys_last ) {
// Complex key, build deep object structure based on a few rules:
// * The 'cur' pointer starts at the object top-level.
// * [] = array push (n is set to array length), [n] = array if n is
// numeric, otherwise object.
// * If at the last keys part, set the value.
// * For each keys part, if the current level is undefined create an
// object or array based on the type of the next keys part.
// * Move the 'cur' pointer to the next level.
// * Rinse & repeat.
for ( ; i <= keys_last; i++ ) {
key = keys[i] === '' ? cur.length : keys[i];
cur = cur[key] = i < keys_last
? cur[key] || ( keys[i+1] && isNaN( keys[i+1] ) ? {} : [] )
: val;
}
} else {
// Simple key, even simpler rules, since only scalars and shallow
// arrays are allowed.
if ( Object.prototype.toString.call( obj[key] ) === '[object Array]' ) {
// val is already an array, so push on the next value.
obj[key].push( val );
} else if ( {}.hasOwnProperty.call(obj, key) ) {
// val isn't an array, but since a second value has been specified,
// convert val into an array.
obj[key] = [ obj[key], val ];
} else {
// val is a scalar.
obj[key] = val;
}
}
} else if ( key ) {
// No value was defined, so set something meaningful.
obj[key] = coerce
? undefined
: '';
}
});
return obj;
};
if ($) {
$.prototype.deparam = $.deparam = deparam;
}
return deparam;
});