diff --git a/json2.js b/json2.js index 5838457..bb18573 100644 --- a/json2.js +++ b/json2.js @@ -1,158 +1,143 @@ -/* - json2.js - 2015-05-03 +// json2.js +// 2016-05-01 +// Public Domain. +// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +// See http://www.JSON.org/js.html +// This code should be minified before deployment. +// See http://javascript.crockford.com/jsmin.html - Public Domain. +// USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO +// NOT CONTROL. - NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. +// This file creates a global JSON object containing two methods: stringify +// and parse. This file is provides the ES5 JSON capability to ES3 systems. +// If a project might run on IE8 or earlier, then this file should be included. +// This file does nothing on ES5 systems. - See http://www.JSON.org/js.html +// JSON.stringify(value, replacer, space) +// value any JavaScript value, usually an object or array. +// replacer an optional parameter that determines how object +// values are stringified for objects. It can be a +// function or an array of strings. +// space an optional parameter that specifies the indentation +// of nested structures. If it is omitted, the text will +// be packed without extra whitespace. If it is a number, +// it will specify the number of spaces to indent at each +// level. If it is a string (such as '\t' or ' '), +// it contains the characters used to indent at each level. +// This method produces a JSON text from a JavaScript value. +// When an object value is found, if the object contains a toJSON +// method, its toJSON method will be called and the result will be +// stringified. A toJSON method does not serialize: it returns the +// value represented by the name/value pair that should be serialized, +// or undefined if nothing should be serialized. The toJSON method +// will be passed the key associated with the value, and this will be +// bound to the value. +// For example, this would serialize Dates as ISO strings. - This code should be minified before deployment. - See http://javascript.crockford.com/jsmin.html +// Date.prototype.toJSON = function (key) { +// function f(n) { +// // Format integers to have at least two digits. +// return n < 10 +// ? '0' + n +// : n; +// } +// return this.getUTCFullYear() + '-' + +// f(this.getUTCMonth() + 1) + '-' + +// f(this.getUTCDate()) + 'T' + +// f(this.getUTCHours()) + ':' + +// f(this.getUTCMinutes()) + ':' + +// f(this.getUTCSeconds()) + 'Z'; +// }; - USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO - NOT CONTROL. +// You can provide an optional replacer method. It will be passed the +// key and value of each member, with this bound to the containing +// object. The value that is returned from your method will be +// serialized. If your method returns undefined, then the member will +// be excluded from the serialization. +// If the replacer parameter is an array of strings, then it will be +// used to select the members to be serialized. It filters the results +// such that only members with keys listed in the replacer array are +// stringified. - This file creates a global JSON object containing two methods: stringify - and parse. This file is provides the ES5 JSON capability to ES3 systems. - If a project might run on IE8 or earlier, then this file should be included. - This file does nothing on ES5 systems. +// Values that do not have JSON representations, such as undefined or +// functions, will not be serialized. Such values in objects will be +// dropped; in arrays they will be replaced with null. You can use +// a replacer function to replace those with JSON values. - JSON.stringify(value, replacer, space) - value any JavaScript value, usually an object or array. +// JSON.stringify(undefined) returns undefined. - replacer an optional parameter that determines how object - values are stringified for objects. It can be a - function or an array of strings. +// The optional space parameter produces a stringification of the +// value that is filled with line breaks and indentation to make it +// easier to read. - space an optional parameter that specifies the indentation - of nested structures. If it is omitted, the text will - be packed without extra whitespace. If it is a number, - it will specify the number of spaces to indent at each - level. If it is a string (such as '\t' or ' '), - it contains the characters used to indent at each level. +// If the space parameter is a non-empty string, then that string will +// be used for indentation. If the space parameter is a number, then +// the indentation will be that many spaces. - This method produces a JSON text from a JavaScript value. +// Example: - When an object value is found, if the object contains a toJSON - method, its toJSON method will be called and the result will be - stringified. A toJSON method does not serialize: it returns the - value represented by the name/value pair that should be serialized, - or undefined if nothing should be serialized. The toJSON method - will be passed the key associated with the value, and this will be - bound to the value +// text = JSON.stringify(['e', {pluribus: 'unum'}]); +// // text is '["e",{"pluribus":"unum"}]' - For example, this would serialize Dates as ISO strings. +// text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); +// // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - Date.prototype.toJSON = function (key) { - function f(n) { - // Format integers to have at least two digits. - return n < 10 - ? '0' + n - : n; - } +// text = JSON.stringify([new Date()], function (key, value) { +// return this[key] instanceof Date +// ? 'Date(' + this[key] + ')' +// : value; +// }); +// // text is '["Date(---current time---)"]' - return this.getUTCFullYear() + '-' + - f(this.getUTCMonth() + 1) + '-' + - f(this.getUTCDate()) + 'T' + - f(this.getUTCHours()) + ':' + - f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; - }; +// JSON.parse(text, reviver) +// This method parses a JSON text to produce an object or array. +// It can throw a SyntaxError exception. - You can provide an optional replacer method. It will be passed the - key and value of each member, with this bound to the containing - object. The value that is returned from your method will be - serialized. If your method returns undefined, then the member will - be excluded from the serialization. +// The optional reviver parameter is a function that can filter and +// transform the results. It receives each of the keys and values, +// and its return value is used instead of the original value. +// If it returns what it received, then the structure is not modified. +// If it returns undefined then the member is deleted. - If the replacer parameter is an array of strings, then it will be - used to select the members to be serialized. It filters the results - such that only members with keys listed in the replacer array are - stringified. +// Example: - Values that do not have JSON representations, such as undefined or - functions, will not be serialized. Such values in objects will be - dropped; in arrays they will be replaced with null. You can use - a replacer function to replace those with JSON values. - JSON.stringify(undefined) returns undefined. +// // Parse the text. Values that look like ISO date strings will +// // be converted to Date objects. - The optional space parameter produces a stringification of the - value that is filled with line breaks and indentation to make it - easier to read. +// myData = JSON.parse(text, function (key, value) { +// var a; +// if (typeof value === 'string') { +// a = +// /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); +// if (a) { +// return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +// +a[5], +a[6])); +// } +// } +// return value; +// }); - If the space parameter is a non-empty string, then that string will - be used for indentation. If the space parameter is a number, then - the indentation will be that many spaces. +// myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { +// var d; +// if (typeof value === 'string' && +// value.slice(0, 5) === 'Date(' && +// value.slice(-1) === ')') { +// d = new Date(value.slice(5, -1)); +// if (d) { +// return d; +// } +// } +// return value; +// }); - Example: +// This is a reference implementation. You are free to copy, modify, or +// redistribute. - text = JSON.stringify(['e', {pluribus: 'unum'}]); - // text is '["e",{"pluribus":"unum"}]' - - - text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); - // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' - - text = JSON.stringify([new Date()], function (key, value) { - return this[key] instanceof Date - ? 'Date(' + this[key] + ')' - : value; - }); - // text is '["Date(---current time---)"]' - - - JSON.parse(text, reviver) - This method parses a JSON text to produce an object or array. - It can throw a SyntaxError exception. - - The optional reviver parameter is a function that can filter and - transform the results. It receives each of the keys and values, - and its return value is used instead of the original value. - If it returns what it received, then the structure is not modified. - If it returns undefined then the member is deleted. - - Example: - - // Parse the text. Values that look like ISO date strings will - // be converted to Date objects. - - myData = JSON.parse(text, function (key, value) { - var a; - if (typeof value === 'string') { - a = -/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); - if (a) { - return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], - +a[5], +a[6])); - } - } - return value; - }); - - myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { - var d; - if (typeof value === 'string' && - value.slice(0, 5) === 'Date(' && - value.slice(-1) === ')') { - d = new Date(value.slice(5, -1)); - if (d) { - return d; - } - } - return value; - }); - - - This is a reference implementation. You are free to copy, modify, or - redistribute. -*/ - -/*jslint - eval, for, this +/*jslint + eval, for, this */ /*property @@ -172,21 +157,21 @@ if (typeof JSON !== 'object') { (function () { 'use strict'; - - var rx_one = /^[\],:{}\s]*$/, - rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, - rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, - rx_four = /(?:^|:|,)(?:\s*\[)+/g, - rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + + var rx_one = /^[\],:{}\s]*$/; + var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; + var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; + var rx_four = /(?:^|:|,)(?:\s*\[)+/g; + var rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; function f(n) { // Format integers to have at least two digits. - return n < 10 - ? '0' + n + return n < 10 + ? '0' + n : n; } - + function this_value() { return this.valueOf(); } @@ -210,10 +195,10 @@ if (typeof JSON !== 'object') { String.prototype.toJSON = this_value; } - var gap, - indent, - meta, - rep; + var gap; + var indent; + var meta; + var rep; function quote(string) { @@ -224,13 +209,13 @@ if (typeof JSON !== 'object') { // sequences. rx_escapable.lastIndex = 0; - return rx_escapable.test(string) + return rx_escapable.test(string) ? '"' + string.replace(rx_escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }) + '"' + }) + '"' : '"' + string + '"'; } @@ -239,13 +224,13 @@ if (typeof JSON !== 'object') { // Produce a string from holder[key]. - var i, // The loop counter. - k, // The member key. - v, // The member value. - length, - mind = gap, - partial, - value = holder[key]; + var i; // The loop counter. + var k; // The member key. + var v; // The member value. + var length; + var mind = gap; + var partial; + var value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value. @@ -271,8 +256,8 @@ if (typeof JSON !== 'object') { // JSON numbers must be finite. Encode non-finite numbers as null. - return isFinite(value) - ? String(value) + return isFinite(value) + ? String(value) : 'null'; case 'boolean': @@ -335,8 +320,8 @@ if (typeof JSON !== 'object') { v = str(k, value); if (v) { partial.push(quote(k) + ( - gap - ? ': ' + gap + ? ': ' : ':' ) + v); } @@ -351,8 +336,8 @@ if (typeof JSON !== 'object') { v = str(k, value); if (v) { partial.push(quote(k) + ( - gap - ? ': ' + gap + ? ': ' : ':' ) + v); } @@ -444,7 +429,9 @@ if (typeof JSON !== 'object') { // The walk method is used to recursively walk the resulting structure so // that modifications can be made. - var k, v, value = holder[key]; + var k; + var v; + var value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) {