| /* |
| json2.js |
| 2008-03-14 |
| |
| Public Domain |
| |
| No warranty expressed or implied. Use at your own risk. |
| |
| See http://www.JSON.org/js.html |
| |
| This is a reference implementation. You are free to copy, modify, or |
| redistribute. |
| |
| Use your own copy. It is extremely unwise to load third party |
| code into your pages. |
| */ |
| |
| if (!this.JSON) { |
| |
| JSON = function () { |
| |
| function f(n) { // Format integers to have at least two digits. |
| return n < 10 ? '0' + n : n; |
| } |
| |
| Date.prototype.toJSON = function () { |
| return this.getUTCFullYear() + '-' + |
| f(this.getUTCMonth() + 1) + '-' + |
| f(this.getUTCDate()) + 'T' + |
| f(this.getUTCHours()) + ':' + |
| f(this.getUTCMinutes()) + ':' + |
| f(this.getUTCSeconds()) + 'Z'; |
| }; |
| |
| |
| var m = { // table of character substitutions |
| '\b': '\\b', |
| '\t': '\\t', |
| '\n': '\\n', |
| '\f': '\\f', |
| '\r': '\\r', |
| '"' : '\\"', |
| '\\': '\\\\' |
| }; |
| |
| function stringify(value, whitelist) { |
| var a, // The array holding the partial texts. |
| i, // The loop counter. |
| k, // The member key. |
| l, // Length. |
| r = /["\\\x00-\x1f\x7f-\x9f]/g, |
| v; // The member value. |
| |
| switch (typeof value) { |
| case 'string': |
| |
| return r.test(value) ? |
| '"' + value.replace(r, function (a) { |
| var c = m[a]; |
| if (c) { |
| return c; |
| } |
| c = a.charCodeAt(); |
| return '\\u00' + Math.floor(c / 16).toString(16) + |
| (c % 16).toString(16); |
| }) + '"' : |
| '"' + value + '"'; |
| |
| case 'number': |
| |
| return isFinite(value) ? String(value) : 'null'; |
| |
| case 'boolean': |
| case 'null': |
| return String(value); |
| |
| case 'object': |
| |
| if (!value) { |
| return 'null'; |
| } |
| |
| if (typeof value.toJSON === 'function') { |
| return stringify(value.toJSON()); |
| } |
| a = []; |
| if (typeof value.length === 'number' && |
| !(value.propertyIsEnumerable('length'))) { |
| |
| l = value.length; |
| for (i = 0; i < l; i += 1) { |
| a.push(stringify(value[i], whitelist) || 'null'); |
| } |
| |
| return '[' + a.join(',') + ']'; |
| } |
| if (whitelist) { |
| l = whitelist.length; |
| for (i = 0; i < l; i += 1) { |
| k = whitelist[i]; |
| if (typeof k === 'string') { |
| v = stringify(value[k], whitelist); |
| if (v) { |
| a.push(stringify(k) + ':' + v); |
| } |
| } |
| } |
| } else { |
| |
| for (k in value) { |
| if (typeof k === 'string') { |
| v = stringify(value[k], whitelist); |
| if (v) { |
| a.push(stringify(k) + ':' + v); |
| } |
| } |
| } |
| } |
| |
| return '{' + a.join(',') + '}'; |
| } |
| } |
| |
| return { |
| stringify: stringify, |
| parse: function (text, filter) { |
| var j; |
| |
| function walk(k, v) { |
| var i, n; |
| if (v && typeof v === 'object') { |
| for (i in v) { |
| if (Object.prototype.hasOwnProperty.apply(v, [i])) { |
| n = walk(i, v[i]); |
| if (n !== undefined) { |
| v[i] = n; |
| } else { |
| delete v[i]; |
| } |
| } |
| } |
| } |
| return filter(k, v); |
| } |
| |
| if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@'). |
| replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). |
| replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { |
| |
| j = eval('(' + text + ')'); |
| |
| return typeof filter === 'function' ? walk('', j) : j; |
| } |
| |
| throw new SyntaxError('parseJSON'); |
| } |
| }; |
| }(); |
| } |