CLIENT GUI Framework
[vnfsdk/refrepo.git] / portal-common / src / main / webapp / common / js / json2.js
1 /*\r
2  * Copyright 2016-2017, CMCC Technologies Co., Ltd.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *         http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 if (typeof JSON !== 'object') {\r
18     JSON = {};\r
19 }\r
20 \r
21 (function () {\r
22     'use strict';\r
23 \r
24     function f(n) {\r
25         // Format integers to have at least two digits.\r
26         return n < 10 ? '0' + n : n;\r
27     }\r
28 \r
29     if (typeof Date.prototype.toJSON !== 'function') {\r
30 \r
31         Date.prototype.toJSON = function (key) {\r
32 \r
33             return isFinite(this.valueOf())\r
34                 ? this.getUTCFullYear()     + '-' +\r
35                     f(this.getUTCMonth() + 1) + '-' +\r
36                     f(this.getUTCDate())      + 'T' +\r
37                     f(this.getUTCHours())     + ':' +\r
38                     f(this.getUTCMinutes())   + ':' +\r
39                     f(this.getUTCSeconds())   + 'Z'\r
40                 : null;\r
41         };\r
42 \r
43         String.prototype.toJSON      =\r
44             Number.prototype.toJSON  =\r
45             Boolean.prototype.toJSON = function (key) {\r
46                 return this.valueOf();\r
47             };\r
48     }\r
49 \r
50     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,\r
51         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,\r
52         gap,\r
53         indent,\r
54         meta = {    // table of character substitutions\r
55             '\b': '\\b',\r
56             '\t': '\\t',\r
57             '\n': '\\n',\r
58             '\f': '\\f',\r
59             '\r': '\\r',\r
60             '"' : '\\"',\r
61             '\\': '\\\\'\r
62         },\r
63         rep;\r
64 \r
65 \r
66     function quote(string) {\r
67 \r
68 // If the string contains no control characters, no quote characters, and no\r
69 // backslash characters, then we can safely slap some quotes around it.\r
70 // Otherwise we must also replace the offending characters with safe escape\r
71 // sequences.\r
72 \r
73         escapable.lastIndex = 0;\r
74         return escapable.test(string) ? '"' + string.replace(escapable, function (a) {\r
75             var c = meta[a];\r
76             return typeof c === 'string'\r
77                 ? c\r
78                 : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r
79         }) + '"' : '"' + string + '"';\r
80     }\r
81 \r
82 \r
83     function str(key, holder) {\r
84 \r
85 // Produce a string from holder[key].\r
86 \r
87         var i,          // The loop counter.\r
88             k,          // The member key.\r
89             v,          // The member value.\r
90             length,\r
91             mind = gap,\r
92             partial,\r
93             value = holder[key];\r
94 \r
95 // If the value has a toJSON method, call it to obtain a replacement value.\r
96 \r
97         if (value && typeof value === 'object' &&\r
98                 typeof value.toJSON === 'function') {\r
99             value = value.toJSON(key);\r
100         }\r
101 \r
102 // If we were called with a replacer function, then call the replacer to\r
103 // obtain a replacement value.\r
104 \r
105         if (typeof rep === 'function') {\r
106             value = rep.call(holder, key, value);\r
107         }\r
108 \r
109 // What happens next depends on the value's type.\r
110 \r
111         switch (typeof value) {\r
112         case 'string':\r
113             return quote(value);\r
114 \r
115         case 'number':\r
116 \r
117 // JSON numbers must be finite. Encode non-finite numbers as null.\r
118 \r
119             return isFinite(value) ? String(value) : 'null';\r
120 \r
121         case 'boolean':\r
122         case 'null':\r
123 \r
124 // If the value is a boolean or null, convert it to a string. Note:\r
125 // typeof null does not produce 'null'. The case is included here in\r
126 // the remote chance that this gets fixed someday.\r
127 \r
128             return String(value);\r
129 \r
130 // If the type is 'object', we might be dealing with an object or an array or\r
131 // null.\r
132 \r
133         case 'object':\r
134 \r
135 // Due to a specification blunder in ECMAScript, typeof null is 'object',\r
136 // so watch out for that case.\r
137 \r
138             if (!value) {\r
139                 return 'null';\r
140             }\r
141 \r
142 // Make an array to hold the partial results of stringifying this object value.\r
143 \r
144             gap += indent;\r
145             partial = [];\r
146 \r
147 // Is the value an array?\r
148 \r
149             if (Object.prototype.toString.apply(value) === '[object Array]') {\r
150 \r
151 // The value is an array. Stringify every element. Use null as a placeholder\r
152 // for non-JSON values.\r
153 \r
154                 length = value.length;\r
155                 for (i = 0; i < length; i += 1) {\r
156                     partial[i] = str(i, value) || 'null';\r
157                 }\r
158 \r
159 // Join all of the elements together, separated with commas, and wrap them in\r
160 // brackets.\r
161 \r
162                 v = partial.length === 0\r
163                     ? '[]'\r
164                     : gap\r
165                     ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'\r
166                     : '[' + partial.join(',') + ']';\r
167                 gap = mind;\r
168                 return v;\r
169             }\r
170 \r
171 // If the replacer is an array, use it to select the members to be stringified.\r
172 \r
173             if (rep && typeof rep === 'object') {\r
174                 length = rep.length;\r
175                 for (i = 0; i < length; i += 1) {\r
176                     if (typeof rep[i] === 'string') {\r
177                         k = rep[i];\r
178                         v = str(k, value);\r
179                         if (v) {\r
180                             partial.push(quote(k) + (gap ? ': ' : ':') + v);\r
181                         }\r
182                     }\r
183                 }\r
184             } else {\r
185 \r
186 // Otherwise, iterate through all of the keys in the object.\r
187 \r
188                 for (k in value) {\r
189                     if (Object.prototype.hasOwnProperty.call(value, k)) {\r
190                         v = str(k, value);\r
191                         if (v) {\r
192                             partial.push(quote(k) + (gap ? ': ' : ':') + v);\r
193                         }\r
194                     }\r
195                 }\r
196             }\r
197 \r
198 // Join all of the member texts together, separated with commas,\r
199 // and wrap them in braces.\r
200 \r
201             v = partial.length === 0\r
202                 ? '{}'\r
203                 : gap\r
204                 ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'\r
205                 : '{' + partial.join(',') + '}';\r
206             gap = mind;\r
207             return v;\r
208         }\r
209     }\r
210 \r
211 // If the JSON object does not yet have a stringify method, give it one.\r
212 \r
213     if (typeof JSON.stringify !== 'function') {\r
214         JSON.stringify = function (value, replacer, space) {\r
215 \r
216 // The stringify method takes a value and an optional replacer, and an optional\r
217 // space parameter, and returns a JSON text. The replacer can be a function\r
218 // that can replace values, or an array of strings that will select the keys.\r
219 // A default replacer method can be provided. Use of the space parameter can\r
220 // produce text that is more easily readable.\r
221 \r
222             var i;\r
223             gap = '';\r
224             indent = '';\r
225 \r
226 // If the space parameter is a number, make an indent string containing that\r
227 // many spaces.\r
228 \r
229             if (typeof space === 'number') {\r
230                 for (i = 0; i < space; i += 1) {\r
231                     indent += ' ';\r
232                 }\r
233 \r
234 // If the space parameter is a string, it will be used as the indent string.\r
235 \r
236             } else if (typeof space === 'string') {\r
237                 indent = space;\r
238             }\r
239 \r
240 // If there is a replacer, it must be a function or an array.\r
241 // Otherwise, throw an error.\r
242 \r
243             rep = replacer;\r
244             if (replacer && typeof replacer !== 'function' &&\r
245                     (typeof replacer !== 'object' ||\r
246                     typeof replacer.length !== 'number')) {\r
247                 throw new Error('JSON.stringify');\r
248             }\r
249 \r
250 // Make a fake root object containing our value under the key of ''.\r
251 // Return the result of stringifying the value.\r
252 \r
253             return str('', {'': value});\r
254         };\r
255     }\r
256 \r
257 \r
258 // If the JSON object does not yet have a parse method, give it one.\r
259 \r
260     if (typeof JSON.parse !== 'function') {\r
261         JSON.parse = function (text, reviver) {\r
262 \r
263 // The parse method takes a text and an optional reviver function, and returns\r
264 // a JavaScript value if the text is a valid JSON text.\r
265 \r
266             var j;\r
267 \r
268             function walk(holder, key) {\r
269 \r
270 // The walk method is used to recursively walk the resulting structure so\r
271 // that modifications can be made.\r
272 \r
273                 var k, v, value = holder[key];\r
274                 if (value && typeof value === 'object') {\r
275                     for (k in value) {\r
276                         if (Object.prototype.hasOwnProperty.call(value, k)) {\r
277                             v = walk(value, k);\r
278                             if (v !== undefined) {\r
279                                 value[k] = v;\r
280                             } else {\r
281                                 delete value[k];\r
282                             }\r
283                         }\r
284                     }\r
285                 }\r
286                 return reviver.call(holder, key, value);\r
287             }\r
288 \r
289 \r
290 // Parsing happens in four stages. In the first stage, we replace certain\r
291 // Unicode characters with escape sequences. JavaScript handles many characters\r
292 // incorrectly, either silently deleting them, or treating them as line endings.\r
293 \r
294             text = String(text);\r
295             cx.lastIndex = 0;\r
296             if (cx.test(text)) {\r
297                 text = text.replace(cx, function (a) {\r
298                     return '\\u' +\r
299                         ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\r
300                 });\r
301             }\r
302 \r
303 // In the second stage, we run the text against regular expressions that look\r
304 // for non-JSON patterns. We are especially concerned with '()' and 'new'\r
305 // because they can cause invocation, and '=' because it can cause mutation.\r
306 // But just to be safe, we want to reject all unexpected forms.\r
307 \r
308 // We split the second stage into 4 regexp operations in order to work around\r
309 // crippling inefficiencies in IE's and Safari's regexp engines. First we\r
310 // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we\r
311 // replace all simple value tokens with ']' characters. Third, we delete all\r
312 // open brackets that follow a colon or comma or that begin the text. Finally,\r
313 // we look to see that the remaining characters are only whitespace or ']' or\r
314 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.\r
315 \r
316             if (/^[\],:{}\s]*$/\r
317                     .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\r
318                         .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')\r
319                         .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {\r
320 \r
321 // In the third stage we use the eval function to compile the text into a\r
322 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity\r
323 // in JavaScript: it can begin a block or an object literal. We wrap the text\r
324 // in parens to eliminate the ambiguity.\r
325 \r
326                 j = eval('(' + text + ')');\r
327 \r
328 // In the optional fourth stage, we recursively walk the new structure, passing\r
329 // each name/value pair to a reviver function for possible transformation.\r
330 \r
331                 return typeof reviver === 'function'\r
332                     ? walk({'': j}, '')\r
333                     : j;\r
334             }\r
335 \r
336 // If the text is not JSON parseable, then a SyntaxError is thrown.\r
337 \r
338             throw new SyntaxError('JSON.parse');\r
339         };\r
340     }\r
341 }());\r