UNPKG

dojo

Version:

Dojo core is a powerful, lightweight library that makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.

163 lines (157 loc) 5.99 kB
define(["./has"], function(has){ "use strict"; var hasJSON = typeof JSON != "undefined"; has.add("json-parse", hasJSON); // all the parsers work fine // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184 has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); /*===== return { // summary: // Functions to parse and serialize JSON parse: function(str, strict){ // summary: // Parses a [JSON](http://json.org) string to return a JavaScript object. // description: // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Throws for invalid JSON strings. This delegates to eval() if native JSON // support is not available. By default this will evaluate any valid JS expression. // With the strict parameter set to true, the parser will ensure that only // valid JSON strings are parsed (otherwise throwing an error). Without the strict // parameter, the content passed to this method must come // from a trusted source. // str: // a string literal of a JSON item, for instance: // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` // strict: // When set to true, this will ensure that only valid, secure JSON is ever parsed. // Make sure this is set to true for untrusted content. Note that on browsers/engines // without native JSON support, setting this to true will run slower. }, stringify: function(value, replacer, spacer){ // summary: // Returns a [JSON](http://json.org) serialization of an object. // description: // Returns a [JSON](http://json.org) serialization of an object. // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) // Note that this doesn't check for infinite recursion, so don't do that! // value: // A value to be serialized. // replacer: // A replacer function that is called for each value and can return a replacement // spacer: // A spacer string to be used for pretty printing of JSON // example: // simple serialization of a trivial object // | define(["dojo/json"], function(JSON){ // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true }); // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); } }; =====*/ if(has("json-stringify")){ return JSON; }else{ var escapeString = function(/*String*/str){ // summary: // Adds escape sequences for non-visual characters, double quote and // backslash and surrounds with double quotes to form a valid string // literal. return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'). replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n"). replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string }; return { parse: has("json-parse") ? JSON.parse : function(str, strict){ if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])*"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){ throw new SyntaxError("Invalid characters in JSON"); } return eval('(' + str + ')'); }, stringify: function(value, replacer, spacer){ var undef; if(typeof replacer == "string"){ spacer = replacer; replacer = null; } function stringify(it, indent, key){ if(replacer){ it = replacer(key, it); } var val, objtype = typeof it; if(objtype == "number"){ return isFinite(it) ? it + "" : "null"; } if(objtype == "boolean"){ return it + ""; } if(it === null){ return "null"; } if(typeof it == "string"){ return escapeString(it); } if(objtype == "function" || objtype == "undefined"){ return undef; // undefined } // short-circuit for objects that support "json" serialization // if they return "self" then just pass-through... if(typeof it.toJSON == "function"){ return stringify(it.toJSON(key), indent, key); } if(it instanceof Date){ return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){ var num = it["getUTC" + prop]() + (plus ? 1 : 0); return num < 10 ? "0" + num : num; }); } if(it.valueOf() !== it){ // primitive wrapper, try again unwrapped: return stringify(it.valueOf(), indent, key); } var nextIndent= spacer ? (indent + spacer) : ""; /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ var sep = spacer ? " " : ""; var newLine = spacer ? "\n" : ""; // array if(it instanceof Array){ var itl = it.length, res = []; for(key = 0; key < itl; key++){ var obj = it[key]; val = stringify(obj, nextIndent, key); if(typeof val != "string"){ val = "null"; } res.push(newLine + nextIndent + val); } return "[" + res.join(",") + newLine + indent + "]"; } // generic object code path var output = []; for(key in it){ var keyStr; if(it.hasOwnProperty(key)){ if(typeof key == "number"){ keyStr = '"' + key + '"'; }else if(typeof key == "string"){ keyStr = escapeString(key); }else{ // skip non-string or number keys continue; } val = stringify(it[key], nextIndent, key); if(typeof val != "string"){ // skip non-serializable values continue; } // At this point, the most non-IE browsers don't get in this branch // (they have native JSON), so push is definitely the way to output.push(newLine + nextIndent + keyStr + ":" + sep + val); } } return "{" + output.join(",") + newLine + indent + "}"; // String } return stringify(value, "", ""); } }; } });