~canonical-isd-hackers/canonical-identity-provider/yubikey-merged

« back to all changes in this revision

Viewing changes to identityprovider/media/src-js/lazrjs/yui/querystring/querystring.js

merged in latest trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
 
3
Code licensed under the BSD License:
 
4
http://developer.yahoo.com/yui/license.html
 
5
version: 3.3.0
 
6
build: 3167
 
7
*/
 
8
YUI.add('querystring-parse', function(Y) {
 
9
 
 
10
/**
 
11
 * <p>The QueryString module adds support for serializing JavaScript objects into
 
12
 * query strings and parsing JavaScript objects from query strings format.</p>
 
13
 *
 
14
 * <p>The QueryString namespace is added to your YUI instance including static methods
 
15
 * Y.QueryString.parse(..) and Y.QueryString.stringify(..).</p>
 
16
 *
 
17
 * <p>The <code>querystring</code> module is a rollup of <code>querystring-parse</code> and
 
18
 * <code>querystring-stringify</code>.</p>
 
19
 *
 
20
 * <p>As their names suggest, <code>querystring-parse</code> adds support for parsing
 
21
 * Query String data (Y.QueryString.parse) and <code>querystring-stringify</code> for serializing
 
22
 * JavaScript data into Query Strings (Y.QueryString.stringify).  You may choose to
 
23
 * include either of the submodules individually if you don't need the
 
24
 * complementary functionality, or include the rollup for both.</p>
 
25
 *
 
26
 * @module querystring
 
27
 * @class QueryString
 
28
 * @static
 
29
 */
 
30
var QueryString = Y.namespace("QueryString"),
 
31
 
 
32
// Parse a key=val string.
 
33
// These can get pretty hairy
 
34
// example flow:
 
35
// parse(foo[bar][][bla]=baz)
 
36
// return parse(foo[bar][][bla],"baz")
 
37
// return parse(foo[bar][], {bla : "baz"})
 
38
// return parse(foo[bar], [{bla:"baz"}])
 
39
// return parse(foo, {bar:[{bla:"baz"}]})
 
40
// return {foo:{bar:[{bla:"baz"}]}}
 
41
pieceParser = function (eq) {
 
42
    return function parsePiece (key, val) {
 
43
 
 
44
        var sliced, numVal, head, tail, ret;
 
45
 
 
46
        if (arguments.length !== 2) {
 
47
            // key=val, called from the map/reduce
 
48
            key = key.split(eq);
 
49
            return parsePiece(
 
50
                QueryString.unescape(key.shift()),
 
51
                QueryString.unescape(key.join(eq))
 
52
            );
 
53
        }
 
54
        key = key.replace(/^\s+|\s+$/g, '');
 
55
        if (Y.Lang.isString(val)) {
 
56
            val = val.replace(/^\s+|\s+$/g, '');
 
57
            // convert numerals to numbers
 
58
            if (!isNaN(val)) {
 
59
                numVal = +val;
 
60
                if (val === numVal.toString(10)) {
 
61
                    val = numVal;
 
62
                }
 
63
            }
 
64
        }
 
65
        sliced = /(.*)\[([^\]]*)\]$/.exec(key);
 
66
        if (!sliced) {
 
67
            ret = {};
 
68
            if (key) {
 
69
                ret[key] = val;
 
70
            }
 
71
            return ret;
 
72
        }
 
73
        // ["foo[][bar][][baz]", "foo[][bar][]", "baz"]
 
74
        tail = sliced[2];
 
75
        head = sliced[1];
 
76
 
 
77
        // array: key[]=val
 
78
        if (!tail) {
 
79
            return parsePiece(head, [val]);
 
80
        }
 
81
 
 
82
        // obj: key[subkey]=val
 
83
        ret = {};
 
84
        ret[tail] = val;
 
85
        return parsePiece(head, ret);
 
86
    };
 
87
},
 
88
 
 
89
// the reducer function that merges each query piece together into one set of params
 
90
mergeParams = function(params, addition) {
 
91
    return (
 
92
        // if it's uncontested, then just return the addition.
 
93
        (!params) ? addition
 
94
        // if the existing value is an array, then concat it.
 
95
        : (Y.Lang.isArray(params)) ? params.concat(addition)
 
96
        // if the existing value is not an array, and either are not objects, arrayify it.
 
97
        : (!Y.Lang.isObject(params) || !Y.Lang.isObject(addition)) ? [params].concat(addition)
 
98
        // else merge them as objects, which is a little more complex
 
99
        : mergeObjects(params, addition)
 
100
    );
 
101
},
 
102
 
 
103
// Merge two *objects* together. If this is called, we've already ruled
 
104
// out the simple cases, and need to do the for-in business.
 
105
mergeObjects = function(params, addition) {
 
106
    for (var i in addition) {
 
107
        if (i && addition.hasOwnProperty(i)) {
 
108
            params[i] = mergeParams(params[i], addition[i]);
 
109
        }
 
110
    }
 
111
    return params;
 
112
};
 
113
 
 
114
/**
 
115
 * Provides Y.QueryString.parse method to accept Query Strings and return native
 
116
 * JavaScript objects.
 
117
 *
 
118
 * @module querystring
 
119
 * @submodule querystring-parse
 
120
 * @for QueryString
 
121
 * @method parse
 
122
 * @param qs {String} Querystring to be parsed into an object.
 
123
 * @param sep {String} (optional) Character that should join param k=v pairs together. Default: "&"
 
124
 * @param eq  {String} (optional) Character that should join keys to their values. Default: "="
 
125
 * @public
 
126
 * @static
 
127
 */
 
128
QueryString.parse = function (qs, sep, eq) {
 
129
    // wouldn't Y.Array(qs.split()).map(pieceParser(eq)).reduce(mergeParams) be prettier?
 
130
    return Y.Array.reduce(
 
131
        Y.Array.map(
 
132
            qs.split(sep || "&"),
 
133
            pieceParser(eq || "=")
 
134
        ),
 
135
        {},
 
136
        mergeParams
 
137
    );
 
138
};
 
139
 
 
140
/**
 
141
 * Provides Y.QueryString.unescape method to be able to override default decoding
 
142
 * method.  This is important in cases where non-standard delimiters are used, if
 
143
 * the delimiters would not normally be handled properly by the builtin
 
144
 * (en|de)codeURIComponent functions.
 
145
 * Default: replace "+" with " ", and then decodeURIComponent behavior.
 
146
 * @module querystring
 
147
 * @submodule querystring-parse
 
148
 * @for QueryString
 
149
 * @method unescape
 
150
 * @param s {String} String to be decoded.
 
151
 * @public
 
152
 * @static
 
153
 **/
 
154
QueryString.unescape = function (s) {
 
155
    return decodeURIComponent(s.replace(/\+/g, ' '));
 
156
};
 
157
 
 
158
 
 
159
 
 
160
 
 
161
 
 
162
}, '3.3.0' ,{requires:['collection']});
 
163
 
 
164
YUI.add('querystring-stringify', function(Y) {
 
165
 
 
166
/**
 
167
 * Provides Y.QueryString.stringify method for converting objects to Query Strings.
 
168
 *
 
169
 * @module querystring
 
170
 * @submodule querystring-stringify
 
171
 * @for QueryString
 
172
 * @static
 
173
 */
 
174
 
 
175
var QueryString = Y.namespace("QueryString"),
 
176
    stack = [],
 
177
    L = Y.Lang;
 
178
 
 
179
/**
 
180
 * Provides Y.QueryString.escape method to be able to override default encoding
 
181
 * method.  This is important in cases where non-standard delimiters are used, if
 
182
 * the delimiters would not normally be handled properly by the builtin
 
183
 * (en|de)codeURIComponent functions.
 
184
 * Default: encodeURIComponent
 
185
 * @module querystring
 
186
 * @submodule querystring-stringify
 
187
 * @for QueryString
 
188
 * @static
 
189
 **/
 
190
QueryString.escape = encodeURIComponent;
 
191
 
 
192
/**
 
193
 * <p>Converts an arbitrary value to a Query String representation.</p>
 
194
 *
 
195
 * <p>Objects with cyclical references will trigger an exception.</p>
 
196
 *
 
197
 * @method stringify
 
198
 * @public
 
199
 * @param obj {Variant} any arbitrary value to convert to query string
 
200
 * @param cfg {Object} (optional) Configuration object.  The three
 
201
 * supported configurations are:
 
202
 * <ul><li>sep: When defined, the value will be used as the key-value
 
203
 * separator.  The default value is "&".</li>
 
204
 * <li>eq: When defined, the value will be used to join the key to
 
205
 * the value.  The default value is "=".</li>
 
206
 * <li>arrayKey: When set to true, the key of an array will have the
 
207
 * '[]' notation appended to the key.  The default value is false.
 
208
 * </li></ul>
 
209
 * @param name {String} (optional) Name of the current key, for handling children recursively.
 
210
 * @static
 
211
 */
 
212
QueryString.stringify = function (obj, c, name) {
 
213
    var begin, end, i, l, n, s,
 
214
        sep = c && c.sep ? c.sep : "&",
 
215
        eq = c && c.eq ? c.eq : "=",
 
216
        aK = c && c.arrayKey ? c.arrayKey : false;
 
217
 
 
218
    if (L.isNull(obj) || L.isUndefined(obj) || L.isFunction(obj)) {
 
219
        return name ? QueryString.escape(name) + eq : '';
 
220
    }
 
221
 
 
222
    if (L.isBoolean(obj) || Object.prototype.toString.call(obj) === '[object Boolean]') {
 
223
        obj =+ obj;
 
224
    }
 
225
 
 
226
    if (L.isNumber(obj) || L.isString(obj)) {
 
227
        return QueryString.escape(name) + eq + QueryString.escape(obj);
 
228
    }
 
229
 
 
230
    if (L.isArray(obj)) {
 
231
        s = [];
 
232
        name = aK ? name + '[]' : name;
 
233
        l = obj.length;
 
234
        for (i = 0; i < l; i++) {
 
235
            s.push( QueryString.stringify(obj[i], c, name) );
 
236
        }
 
237
 
 
238
        return s.join(sep);
 
239
    }
 
240
    // now we know it's an object.
 
241
 
 
242
    // Check for cyclical references in nested objects
 
243
    for (i = stack.length - 1; i >= 0; --i) {
 
244
        if (stack[i] === obj) {
 
245
            throw new Error("QueryString.stringify. Cyclical reference");
 
246
        }
 
247
    }
 
248
 
 
249
    stack.push(obj);
 
250
    s = [];
 
251
    begin = name ? name + '[' : '';
 
252
    end = name ? ']' : '';
 
253
    for (i in obj) {
 
254
        if (obj.hasOwnProperty(i)) {
 
255
            n = begin + i + end;
 
256
            s.push(QueryString.stringify(obj[i], c, n));
 
257
        }
 
258
    }
 
259
 
 
260
    stack.pop();
 
261
    s = s.join(sep);
 
262
    if (!s && name) {
 
263
        return name + "=";
 
264
    }
 
265
 
 
266
    return s;
 
267
};
 
268
 
 
269
 
 
270
 
 
271
}, '3.3.0' );
 
272
 
 
273
 
 
274
 
 
275
YUI.add('querystring', function(Y){}, '3.3.0' ,{use:['querystring-parse', 'querystring-stringify']});
 
276