/* * jQuery JSON Plugin * version: 1.0 (2008-04-17) * * This document is licensed as free software under the terms of the * MIT License: http://www.opensource.org/licenses/mit-license.php * * Brantley Harris technically wrote this plugin, but it is based somewhat * on the JSON.org website's http://www.json.org/json2.js, which proclaims: * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that * I uphold. I really just cleaned it up. * * It is also based heavily on MochiKit's serializeJSON, which is * copywrited 2005 by Bob Ippolito. */ (function($) { function toIntegersAtLease(n) // Format integers to have at least two digits. { return n < 10 ? '0' + n : n; } Date.prototype.toJSON = function(date) // Yes, it polutes the Date namespace, but we'll allow it here, as // it's damned usefull. { return this.getUTCFullYear() + '-' + toIntegersAtLease(this.getUTCMonth()) + '-' + toIntegersAtLease(this.getUTCDate()); }; var escapeable = /["\\\x00-\x1f\x7f-\x9f]/g; var meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\' }; $.quoteString = function(string) // Places quotes around a string, inteligently. // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. { if (escapeable.test(string)) { return '"' + string.replace(escapeable, function (a) { var c = meta[a]; if (typeof c === 'string') { return c; } c = a.charCodeAt(); return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); }) + '"'; } return '"' + string + '"'; }; $.toJSON = function(o, compact) { var type = typeof(o); if (type == "undefined") return "undefined"; else if (type == "number" || type == "boolean") return o + ""; else if (o === null) return "null"; // Is it a string? if (type == "string") { return $.quoteString(o); } // Does it have a .toJSON function? if (type == "object" && typeof o.toJSON == "function") return o.toJSON(compact); // Is it an array? if (type != "function" && typeof(o.length) == "number") { var ret = []; for (var i = 0; i < o.length; i++) { ret.push( $.toJSON(o[i], compact) ); } if (compact) return "[" + ret.join(",") + "]"; else return "[" + ret.join(", ") + "]"; } // If it's a function, we have to warn somebody! if (type == "function") { throw new TypeError("Unable to convert object of type 'function' to json."); } // It's probably an object, then. var ret = []; for (var k in o) { var name; type = typeof(k); if (type == "number") name = '"' + k + '"'; else if (type == "string") name = $.quoteString(k); else continue; //skip non-string or number keys var val = $.toJSON(o[k], compact); if (typeof(val) != "string") { // skip non-serializable values continue; } if (compact) ret.push(name + ":" + val); else ret.push(name + ": " + val); } return "{" + ret.join(", ") + "}"; }; $.compactJSON = function(o) { return $.toJSON(o, true); }; $.evalJSON = function(src) // Evals JSON that we know to be safe. { return eval("(" + src + ")"); }; $.secureEvalJSON = function(src) // Evals JSON in a way that is *more* secure. { var filtered = src; filtered = filtered.replace(/\\["\\\/bfnrtu]/g, '@'); filtered = filtered.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); filtered = filtered.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); if (/^[\],:{}\s]*$/.test(filtered)) return eval("(" + src + ")"); else throw new SyntaxError("Error parsing JSON, source is not valid."); }; })(jQuery);