]> git.wh0rd.org Git - tt-rss.git/blob - lib/dojo/json.js.uncompressed.js
d77bf5a960ca62ee7ddd45220af88dc842677764
[tt-rss.git] / lib / dojo / json.js.uncompressed.js
1 define("dojo/json", ["./has"], function(has){
2         "use strict";
3         var hasJSON = typeof JSON != "undefined";
4         has.add("json-parse", hasJSON); // all the parsers work fine
5                 // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
6         has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
7
8         /*=====
9         return {
10                 // summary:
11                 //              Functions to parse and serialize JSON
12
13                 parse: function(str, strict){
14                         // summary:
15                         //              Parses a [JSON](http://json.org) string to return a JavaScript object.
16                         // description:
17                         //              This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
18                         //              Throws for invalid JSON strings. This delegates to eval() if native JSON
19                         //              support is not available. By default this will evaluate any valid JS expression.
20                         //              With the strict parameter set to true, the parser will ensure that only
21                         //              valid JSON strings are parsed (otherwise throwing an error). Without the strict
22                         //              parameter, the content passed to this method must come
23                         //              from a trusted source.
24                         // str:
25                         //              a string literal of a JSON item, for instance:
26                         //              `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
27                         // strict:
28                         //              When set to true, this will ensure that only valid, secure JSON is ever parsed.
29                         //              Make sure this is set to true for untrusted content. Note that on browsers/engines
30                         //              without native JSON support, setting this to true will run slower.
31                 },
32                 stringify: function(value, replacer, spacer){
33                         // summary:
34                         //              Returns a [JSON](http://json.org) serialization of an object.
35                         // description:
36                         //              Returns a [JSON](http://json.org) serialization of an object.
37                         //              This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
38                         //              Note that this doesn't check for infinite recursion, so don't do that!
39                         // value:
40                         //              A value to be serialized.
41                         // replacer:
42                         //              A replacer function that is called for each value and can return a replacement
43                         // spacer:
44                         //              A spacer string to be used for pretty printing of JSON
45                         // example:
46                         //              simple serialization of a trivial object
47                         //      |       define(["dojo/json"], function(JSON){
48                         //      |               var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
49                         //      |               doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
50                 }
51         };
52         =====*/
53
54         if(has("json-stringify")){
55                 return JSON;
56         }else{
57                 var escapeString = function(/*String*/str){
58                         // summary:
59                         //              Adds escape sequences for non-visual characters, double quote and
60                         //              backslash and surrounds with double quotes to form a valid string
61                         //              literal.
62                         return ('"' + str.replace(/(["\\])/g, '\\$1') + '"').
63                                 replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").
64                                 replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string
65                 };
66                 return {
67                         parse: has("json-parse") ? JSON.parse : function(str, strict){
68                                 if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
69                                         throw new SyntaxError("Invalid characters in JSON");
70                                 }
71                                 return eval('(' + str + ')');
72                         },
73                         stringify: function(value, replacer, spacer){
74                                 var undef;
75                                 if(typeof replacer == "string"){
76                                         spacer = replacer;
77                                         replacer = null;
78                                 }
79                                 function stringify(it, indent, key){
80                                         if(replacer){
81                                                 it = replacer(key, it);
82                                         }
83                                         var val, objtype = typeof it;
84                                         if(objtype == "number"){
85                                                 return isFinite(it) ? it + "" : "null";
86                                         }
87                                         if(objtype == "boolean"){
88                                                 return it + "";
89                                         }
90                                         if(it === null){
91                                                 return "null";
92                                         }
93                                         if(typeof it == "string"){
94                                                 return escapeString(it);
95                                         }
96                                         if(objtype == "function" || objtype == "undefined"){
97                                                 return undef; // undefined
98                                         }
99                                         // short-circuit for objects that support "json" serialization
100                                         // if they return "self" then just pass-through...
101                                         if(typeof it.toJSON == "function"){
102                                                 return stringify(it.toJSON(key), indent, key);
103                                         }
104                                         if(it instanceof Date){
105                                                 return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){
106                                                         var num = it["getUTC" + prop]() + (plus ? 1 : 0);
107                                                         return num < 10 ? "0" + num : num;
108                                                 });
109                                         }
110                                         if(it.valueOf() !== it){
111                                                 // primitive wrapper, try again unwrapped:
112                                                 return stringify(it.valueOf(), indent, key);
113                                         }
114                                         var nextIndent= spacer ? (indent + spacer) : "";
115                                         /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ 
116                                 
117                                         var sep = spacer ? " " : "";
118                                         var newLine = spacer ? "\n" : "";
119                                 
120                                         // array
121                                         if(it instanceof Array){
122                                                 var itl = it.length, res = [];
123                                                 for(key = 0; key < itl; key++){
124                                                         var obj = it[key];
125                                                         val = stringify(obj, nextIndent, key);
126                                                         if(typeof val != "string"){
127                                                                 val = "null";
128                                                         }
129                                                         res.push(newLine + nextIndent + val);
130                                                 }
131                                                 return "[" + res.join(",") + newLine + indent + "]";
132                                         }
133                                         // generic object code path
134                                         var output = [];
135                                         for(key in it){
136                                                 var keyStr;
137                                                 if(it.hasOwnProperty(key)){
138                                                         if(typeof key == "number"){
139                                                                 keyStr = '"' + key + '"';
140                                                         }else if(typeof key == "string"){
141                                                                 keyStr = escapeString(key);
142                                                         }else{
143                                                                 // skip non-string or number keys
144                                                                 continue;
145                                                         }
146                                                         val = stringify(it[key], nextIndent, key);
147                                                         if(typeof val != "string"){
148                                                                 // skip non-serializable values
149                                                                 continue;
150                                                         }
151                                                         // At this point, the most non-IE browsers don't get in this branch 
152                                                         // (they have native JSON), so push is definitely the way to
153                                                         output.push(newLine + nextIndent + keyStr + ":" + sep + val);
154                                                 }
155                                         }
156                                         return "{" + output.join(",") + newLine + indent + "}"; // String
157                                 }
158                                 return stringify(value, "", "");
159                         }
160                 };
161         }
162 });