webui-aria2/js/libs/dojo/json.js.uncompressed.js
2012-05-01 19:52:07 +08:00

151 lines
5.7 KiB
JavaScript

//>>built
define("dojo/json", ["./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}');
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){
// 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.
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){
// 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);
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(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, "", "");
}
};
}
});