json-stringify.js revision 34d05a0baa83aa231e5faed818bc6ab5112cf2bf
* Provides Y.json.stringify method for converting objects to JSON strings. YUI.
add(
'json-stringify',
function (Y) {
* Regex used to replace special characters in strings for JSON * @property _SPECIAL_CHARS * Character substitution map for common escapes and special characters. * Serializes a Date instance as a UTC date string. Used internally by * stringify. Override this method if you need Dates serialized in a * @param d {Date} The Date to serialize * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ dateToString : function (d) { return v < 10 ? '0' + v : v; return '"' + d.getUTCFullYear() + '-
' + _zeroPad(d.getUTCMonth() + 1) + '-
' + _zeroPad(d.getUTCDate()) + 'T
' + _zeroPad(d.getUTCHours()) + ':
' + _zeroPad(d.getUTCMinutes()) + ':
' + _zeroPad(d.getUTCSeconds()) + 'Z
"'; * Converts an arbitrary value to a JSON string representation. * Cyclical object or array references are replaced with null. * If a whitelist is provided, only matching object keys will be included. * If a depth limit is provided, objects and arrays at that depth will * be stringified as empty. * @param o {MIXED} any arbitrary object to convert to JSON string * @param w {Array} (optional) whitelist of acceptable object keys to include * @param d {number} (optional) depth limit to recurse objects/arrays (practical minimum 1) * @return {string} JSON string representation of the input stringify : function (o,w,d) { str_re = Y.json._SPECIAL_CHARS, rep = typeof w === 'function' ? w : null, pstack = []; // Processing stack used for cyclical ref protection if (rep || typeof w !== 'object') { // escape encode special characters var _char = function (c) { m[c] = '\\u00' + Math.floor(a / 16).toString(16) + // Enclose the escaped string in double quotes var _string = function (s) { return '"' + s.replace(str_re, _char) + '"'; // Use the configured date conversion var _date = Y.json.dateToString; // Worker function. Fork behavior on data type and recurse objects and // arrays per the configured depth. var _stringify = function (h,key,d) { var o = typeof rep === 'function' ? rep.call(h,key,h[key]) : h[key], i,len,j, // array iteration vt, // typeof v during iteration a; // composition array for performance over string concat // native boolean and Boolean instance if (t === 'boolean' || o instanceof Boolean) { // native number and Number instance if (t === 'number' || o instanceof Number) { return isFinite(o) ? String(o) : 'null'; // Check for cyclical references for (i = pstack.length - 1; i >= 0; --i) { // Add the object to the processing stack pstack[pstack.length] = o; // Only recurse if we're above depth config for (i = o.length - 1; i >= 0; --i) { a[i] = _stringify(o,i,d-1) || 'null'; // remove the array from the stack return '[' + a.join(',') + ']'; // If whitelist provided, take only those keys w = Y.lang.isArray(w) ? w : Y.object.keys(w||o); for (i = 0, j = 0, len = w.length; i < len; ++i) { if (typeof w[i] === 'string') { v = _stringify(o,w[i],d-1); a[j++] = _string(w[i]) + ':' + v; // Remove the object from processing stack return '{' + a.join(',') + '}'; return undefined; // invalid input // Default depth to POSITIVE_INFINITY return _stringify({'':o},'',d);