MDL-32843 import YUI 3.5.1
[moodle.git] / lib / yui / 3.5.1 / build / json-parse / json-parse-debug.js
blob072950bff300fc43abfe03dd1b4c64a804ae9efd
1 /*
2 YUI 3.5.1 (build 22)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('json-parse', function(Y) {
9 /**
10  * <p>The JSON module adds support for serializing JavaScript objects into
11  * JSON strings and parsing JavaScript objects from strings in JSON format.</p>
12  *
13  * <p>The JSON namespace is added to your YUI instance including static methods
14  * Y.JSON.parse(..) and Y.JSON.stringify(..).</p>
15  *
16  * <p>The functionality and method signatures follow the ECMAScript 5
17  * specification.  In browsers with native JSON support, the native
18  * implementation is used.</p>
19  *
20  * <p>The <code>json</code> module is a rollup of <code>json-parse</code> and
21  * <code>json-stringify</code>.</p>
22  * 
23  * <p>As their names suggest, <code>json-parse</code> adds support for parsing
24  * JSON data (Y.JSON.parse) and <code>json-stringify</code> for serializing
25  * JavaScript data into JSON strings (Y.JSON.stringify).  You may choose to
26  * include either of the submodules individually if you don't need the
27  * complementary functionality, or include the rollup for both.</p>
28  *
29  * @module json
30  * @main json
31  * @class JSON
32  * @static
33  */
35 /**
36  * Provides Y.JSON.parse method to accept JSON strings and return native
37  * JavaScript objects.
38  *
39  * @module json
40  * @submodule json-parse
41  * @for JSON
42  * @static
43  */
46 // All internals kept private for security reasons
47 function fromGlobal(ref) {
48     return (Y.config.win || this || {})[ref];
52     /**
53      * Alias to native browser implementation of the JSON object if available.
54      *
55      * @property Native
56      * @type {Object}
57      * @private
58      */
59 var _JSON  = fromGlobal('JSON'),
61     Native = (Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON),
62     useNative = !!Native,
64     /**
65      * Replace certain Unicode characters that JavaScript may handle incorrectly
66      * during eval--either by deleting them or treating them as line
67      * endings--with escape sequences.
68      * IMPORTANT NOTE: This regex will be used to modify the input if a match is
69      * found.
70      *
71      * @property _UNICODE_EXCEPTIONS
72      * @type {RegExp}
73      * @private
74      */
75     _UNICODE_EXCEPTIONS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
78     /**
79      * First step in the safety evaluation.  Regex used to replace all escape
80      * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
81      *
82      * @property _ESCAPES
83      * @type {RegExp}
84      * @private
85      */
86     _ESCAPES = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
88     /**
89      * Second step in the safety evaluation.  Regex used to replace all simple
90      * values with ']' characters.
91      *
92      * @property _VALUES
93      * @type {RegExp}
94      * @private
95      */
96     _VALUES  = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
98     /**
99      * Third step in the safety evaluation.  Regex used to remove all open
100      * square brackets following a colon, comma, or at the beginning of the
101      * string.
102      *
103      * @property _BRACKETS
104      * @type {RegExp}
105      * @private
106      */
107     _BRACKETS = /(?:^|:|,)(?:\s*\[)+/g,
109     /**
110      * Final step in the safety evaluation.  Regex used to test the string left
111      * after all previous replacements for invalid characters.
112      *
113      * @property _UNSAFE
114      * @type {RegExp}
115      * @private
116      */
117     _UNSAFE = /[^\],:{}\s]/,
118     
119     /**
120      * Replaces specific unicode characters with their appropriate \unnnn
121      * format. Some browsers ignore certain characters during eval.
122      *
123      * @method escapeException
124      * @param c {String} Unicode character
125      * @return {String} the \unnnn escapement of the character
126      * @private
127      */
128     _escapeException = function (c) {
129         return '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
130     },
132     /**
133      * Traverses nested objects, applying a reviver function to each (key,value)
134      * from the scope if the key:value's containing object.  The value returned
135      * from the function will replace the original value in the key:value pair.
136      * If the value returned is undefined, the key will be omitted from the
137      * returned object.
138      *
139      * @method _revive
140      * @param data {MIXED} Any JavaScript data
141      * @param reviver {Function} filter or mutation function
142      * @return {MIXED} The results of the filtered data
143      * @private
144      */
145     _revive = function (data, reviver) {
146         var walk = function (o,key) {
147             var k,v,value = o[key];
148             if (value && typeof value === 'object') {
149                 for (k in value) {
150                     if (value.hasOwnProperty(k)) {
151                         v = walk(value, k);
152                         if (v === undefined) {
153                             delete value[k];
154                         } else {
155                             value[k] = v;
156                         }
157                     }
158                 }
159             }
160             return reviver.call(o,key,value);
161         };
163         return typeof reviver === 'function' ? walk({'':data},'') : data;
164     },
166     /**
167      * Parse a JSON string, returning the native JavaScript representation.
168      *
169      * @param s {string} JSON string data
170      * @param reviver {function} (optional) function(k,v) passed each key value
171      *          pair of object literals, allowing pruning or altering values
172      * @return {MIXED} the native JavaScript representation of the JSON string
173      * @throws SyntaxError
174      * @method parse
175      * @static
176      */
177     // JavaScript implementation in lieu of native browser support.  Based on
178     // the json2.js library from http://json.org
179     _parse = function (s,reviver) {
180         // Replace certain Unicode characters that are otherwise handled
181         // incorrectly by some browser implementations.
182         // NOTE: This modifies the input if such characters are found!
183         s = s.replace(_UNICODE_EXCEPTIONS, _escapeException);
184         
185         // Test for any remaining invalid characters
186         if (!_UNSAFE.test(s.replace(_ESCAPES,'@').
187                             replace(_VALUES,']').
188                             replace(_BRACKETS,''))) {
190             // Eval the text into a JavaScript data structure, apply any
191             // reviver function, and return
192             return _revive( eval('(' + s + ')'), reviver );
193         }
195         throw new SyntaxError('JSON.parse');
196     };
197     
198 Y.namespace('JSON').parse = function (s,reviver) {
199         if (typeof s !== 'string') {
200             s += '';
201         }
203         return Native && Y.JSON.useNativeParse ?
204             Native.parse(s,reviver) : _parse(s,reviver);
207 function workingNative( k, v ) {
208     return k === "ok" ? true : v;
211 // Double check basic functionality.  This is mainly to catch early broken
212 // implementations of the JSON API in Firefox 3.1 beta1 and beta2
213 if ( Native ) {
214     try {
215         useNative = ( Native.parse( '{"ok":false}', workingNative ) ).ok;
216     }
217     catch ( e ) {
218         useNative = false;
219     }
223  * Leverage native JSON parse if the browser has a native implementation.
224  * In general, this is a good idea.  See the Known Issues section in the
225  * JSON user guide for caveats.  The default value is true for browsers with
226  * native JSON support.
228  * @property useNativeParse
229  * @type Boolean
230  * @default true
231  * @static
232  */
233 Y.JSON.useNativeParse = useNative;
236 }, '3.5.1' ,{requires:['yui-base']});