Changeset View
Changeset View
Standalone View
Standalone View
externals/javelin/src/lib/JSON.js
- This file was added.
| /** | |||||
| * Simple JSON serializer. | |||||
| * | |||||
| * @requires javelin-install | |||||
| * @provides javelin-json | |||||
| * @javelin | |||||
| */ | |||||
| /** | |||||
| * JSON serializer and parser. This class uses the native JSON parser if it is | |||||
| * available; if not, it provides an eval-based parser and a simple serializer. | |||||
| * | |||||
| * NOTE: This class uses eval() on some systems, without sanitizing input. It is | |||||
| * not safe to use with untrusted data. Javelin does not provide a library | |||||
| * suitable for parsing untrusted JSON. | |||||
| * | |||||
| * Usage is straightforward: | |||||
| * | |||||
| * JX.JSON.stringify({"bees":"knees"}); // Returns string: '{"bees":"knees"}' | |||||
| * JX.JSON.parse('{"bees":"knees"}'); // Returns object: {"bees":"knees"} | |||||
| * | |||||
| * @task json JSON Manipulation | |||||
| * @task internal Internal | |||||
| * @group util | |||||
| */ | |||||
| JX.install('JSON', { | |||||
| statics : { | |||||
| /* -( JSON Manipulation )-------------------------------------------------- */ | |||||
| /** | |||||
| * Parse a **trusted** JSON string into an object. Accepts a valid JSON | |||||
| * string and returns the object it encodes. | |||||
| * | |||||
| * NOTE: This method does not sanitize input and uses an eval-based parser | |||||
| * on some systems. It is **NOT SAFE** to use with untrusted inputs. | |||||
| * | |||||
| * @param string A valid, trusted JSON string. | |||||
| * @return object The object encoded by the JSON string. | |||||
| * @task json | |||||
| */ | |||||
| parse : function(data) { | |||||
| if (typeof data != 'string') { | |||||
| return null; | |||||
| } | |||||
| if (window.JSON && JSON.parse) { | |||||
| var obj; | |||||
| try { | |||||
| obj = JSON.parse(data); | |||||
| } catch (e) {} | |||||
| return obj || null; | |||||
| } | |||||
| return eval('(' + data + ')'); | |||||
| }, | |||||
| /** | |||||
| * Serialize an object into a JSON string. Accepts an object comprised of | |||||
| * maps, lists and scalars and transforms it into a JSON representation. | |||||
| * This method has undefined behavior if you pass in other complicated | |||||
| * things, e.g. object graphs containing cycles, document.body, or Date | |||||
| * objects. | |||||
| * | |||||
| * @param object An object comprised of maps, lists and scalars. | |||||
| * @return string JSON representation of the object. | |||||
| * @task json | |||||
| */ | |||||
| stringify : function(val) { | |||||
| if (window.JSON && JSON.stringify) { | |||||
| return JSON.stringify(val); | |||||
| } | |||||
| var out = []; | |||||
| if ( | |||||
| val === null || val === true || val === false || typeof val == 'number' | |||||
| ) { | |||||
| return '' + val; | |||||
| } | |||||
| if (val.push && val.pop) { | |||||
| var v; | |||||
| for (var ii = 0; ii < val.length; ii++) { | |||||
| // For consistency with JSON.stringify(), encode undefined array | |||||
| // indices as null. | |||||
| v = (typeof val[ii] == 'undefined') ? null : val[ii]; | |||||
| out.push(JX.JSON.stringify(v)); | |||||
| } | |||||
| return '[' + out.join(',') + ']'; | |||||
| } | |||||
| if (typeof val == 'string') { | |||||
| return JX.JSON._esc(val); | |||||
| } | |||||
| for (var k in val) { | |||||
| out.push(JX.JSON._esc(k) + ':' + JX.JSON.stringify(val[k])); | |||||
| } | |||||
| return '{' + out.join(',') + '}'; | |||||
| }, | |||||
| /* -( Internal )----------------------------------------------------------- */ | |||||
| // Lifted more or less directly from Crockford's JSON2. | |||||
| _escexp : /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | |||||
| // List of control character escape codes. | |||||
| _meta : { | |||||
| '\b' : '\\b', | |||||
| '\t' : '\\t', | |||||
| '\n' : '\\n', | |||||
| '\f' : '\\f', | |||||
| '\r' : '\\r', | |||||
| '"' : '\\"', | |||||
| '\\' : '\\\\' | |||||
| }, | |||||
| /** | |||||
| * Quote and escape a string for inclusion in serialized JSON. Finds | |||||
| * characters in the string which need to be escaped and uses | |||||
| * @{method:_replace} to escape them. | |||||
| * | |||||
| * @param string Unescaped string. | |||||
| * @return string Escaped string. | |||||
| * @task internal | |||||
| */ | |||||
| _esc : function(str) { | |||||
| JX.JSON._escexp.lastIndex = 0; | |||||
| return JX.JSON._escexp.test(str) ? | |||||
| '"' + str.replace(JX.JSON._escexp, JX.JSON._replace) + '"' : | |||||
| '"' + str + '"'; | |||||
| }, | |||||
| /** | |||||
| * Helper callback for @{method:_esc}, escapes characters which can't be | |||||
| * represented normally in serialized JSON. | |||||
| * | |||||
| * @param string Unescaped character. | |||||
| * @return string Escaped character. | |||||
| * @task internal | |||||
| */ | |||||
| _replace : function(m) { | |||||
| if (m in JX.JSON._meta) { | |||||
| return JX.JSON._meta[m]; | |||||
| } | |||||
| return '\\u' + (('0000' + m.charCodeAt(0).toString(16)).slice(-4)); | |||||
| } | |||||
| } | |||||
| }); | |||||