/* * 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) { 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(); // 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]) ); } 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]); if (typeof(val) != "string") { // skip non-serializable values continue; } 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);