src/cm/media/js/lib/yui/yui3.0.0/build/json/json-debug.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0
       
     6 build: 1549
       
     7 */
       
     8 YUI.add('json-parse', function(Y) {
       
     9 
       
    10 /**
       
    11  * <p>The JSON module adds support for serializing JavaScript objects into
       
    12  * JSON strings and parsing JavaScript objects from strings in JSON format.</p>
       
    13  *
       
    14  * <p>The JSON namespace is added to your YUI instance including static methods
       
    15  * Y.JSON.parse(..) and Y.JSON.stringify(..).</p>
       
    16  *
       
    17  * <p>The functionality and method signatures follow the ECMAScript 5
       
    18  * specification.  In browsers with native JSON support, the native
       
    19  * implementation is used.</p>
       
    20  *
       
    21  * <p>The <code>json</code> module is a rollup of <code>json-parse</code> and
       
    22  * <code>json-stringify</code>.</p>
       
    23  * 
       
    24  * <p>As their names suggest, <code>json-parse</code> adds support for parsing
       
    25  * JSON data (Y.JSON.parse) and <code>json-stringify</code> for serializing
       
    26  * JavaScript data into JSON strings (Y.JSON.stringify).  You may choose to
       
    27  * include either of the submodules individually if you don't need the
       
    28  * complementary functionality, or include the rollup for both.</p>
       
    29  *
       
    30  * @module json
       
    31  * @class JSON
       
    32  * @static
       
    33  */
       
    34 
       
    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  */
       
    44 
       
    45 
       
    46 // All internals kept private for security reasons
       
    47 
       
    48 
       
    49     /**
       
    50      * Alias to native browser implementation of the JSON object if available.
       
    51      *
       
    52      * @property Native
       
    53      * @type {Object}
       
    54      * @private
       
    55      */
       
    56 var _JSON  = Y.config.win.JSON,
       
    57     Native = (Object.prototype.toString.call(_JSON) === '[object JSON]' && _JSON),
       
    58 
       
    59     /**
       
    60      * Replace certain Unicode characters that JavaScript may handle incorrectly
       
    61      * during eval--either by deleting them or treating them as line
       
    62      * endings--with escape sequences.
       
    63      * IMPORTANT NOTE: This regex will be used to modify the input if a match is
       
    64      * found.
       
    65      *
       
    66      * @property _UNICODE_EXCEPTIONS
       
    67      * @type {RegExp}
       
    68      * @private
       
    69      */
       
    70     _UNICODE_EXCEPTIONS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
       
    71 
       
    72 
       
    73     /**
       
    74      * First step in the safety evaluation.  Regex used to replace all escape
       
    75      * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
       
    76      *
       
    77      * @property _ESCAPES
       
    78      * @type {RegExp}
       
    79      * @private
       
    80      */
       
    81     _ESCAPES = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
       
    82 
       
    83     /**
       
    84      * Second step in the safety evaluation.  Regex used to replace all simple
       
    85      * values with ']' characters.
       
    86      *
       
    87      * @property _VALUES
       
    88      * @type {RegExp}
       
    89      * @private
       
    90      */
       
    91     _VALUES  = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
       
    92 
       
    93     /**
       
    94      * Third step in the safety evaluation.  Regex used to remove all open
       
    95      * square brackets following a colon, comma, or at the beginning of the
       
    96      * string.
       
    97      *
       
    98      * @property _BRACKETS
       
    99      * @type {RegExp}
       
   100      * @private
       
   101      */
       
   102     _BRACKETS = /(?:^|:|,)(?:\s*\[)+/g,
       
   103 
       
   104     /**
       
   105      * Final step in the safety evaluation.  Regex used to test the string left
       
   106      * after all previous replacements for invalid characters.
       
   107      *
       
   108      * @property _UNSAFE
       
   109      * @type {RegExp}
       
   110      * @private
       
   111      */
       
   112     _UNSAFE = /[^\],:{}\s]/,
       
   113     
       
   114     /**
       
   115      * Replaces specific unicode characters with their appropriate \unnnn
       
   116      * format. Some browsers ignore certain characters during eval.
       
   117      *
       
   118      * @method escapeException
       
   119      * @param c {String} Unicode character
       
   120      * @return {String} the \unnnn escapement of the character
       
   121      * @private
       
   122      */
       
   123     _escapeException = function (c) {
       
   124         return '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
       
   125     },
       
   126 
       
   127     /**
       
   128      * Traverses nested objects, applying a reviver function to each (key,value)
       
   129      * from the scope if the key:value's containing object.  The value returned
       
   130      * from the function will replace the original value in the key:value pair.
       
   131      * If the value returned is undefined, the key will be omitted from the
       
   132      * returned object.
       
   133      *
       
   134      * @method _revive
       
   135      * @param data {MIXED} Any JavaScript data
       
   136      * @param reviver {Function} filter or mutation function
       
   137      * @return {MIXED} The results of the filtered data
       
   138      * @private
       
   139      */
       
   140     _revive = function (data, reviver) {
       
   141         var walk = function (o,key) {
       
   142             var k,v,value = o[key];
       
   143             if (value && typeof value === 'object') {
       
   144                 for (k in value) {
       
   145                     if (value.hasOwnProperty(k)) {
       
   146                         v = walk(value, k);
       
   147                         if (v === undefined) {
       
   148                             delete value[k];
       
   149                         } else {
       
   150                             value[k] = v;
       
   151                         }
       
   152                     }
       
   153                 }
       
   154             }
       
   155             return reviver.call(o,key,value);
       
   156         };
       
   157 
       
   158         return typeof reviver === 'function' ? walk({'':data},'') : data;
       
   159     },
       
   160 
       
   161     /**
       
   162      * Parse a JSON string, returning the native JavaScript representation.
       
   163      *
       
   164      * @param s {string} JSON string data
       
   165      * @param reviver {function} (optional) function(k,v) passed each key value
       
   166      *          pair of object literals, allowing pruning or altering values
       
   167      * @return {MIXED} the native JavaScript representation of the JSON string
       
   168      * @throws SyntaxError
       
   169      * @method parse
       
   170      * @static
       
   171      */
       
   172     // JavaScript implementation in lieu of native browser support.  Based on
       
   173     // the json2.js library from http://json.org
       
   174     _parse = function (s,reviver) {
       
   175         if (typeof s === 'string') {
       
   176             // Replace certain Unicode characters that are otherwise handled
       
   177             // incorrectly by some browser implementations.
       
   178             // NOTE: This modifies the input if such characters are found!
       
   179             s = s.replace(_UNICODE_EXCEPTIONS, _escapeException);
       
   180             
       
   181             // Test for any remaining invalid characters
       
   182             if (!_UNSAFE.test(s.replace(_ESCAPES,'@').
       
   183                                  replace(_VALUES,']').
       
   184                                  replace(_BRACKETS,''))) {
       
   185 
       
   186                 // Eval the text into a JavaScript data structure, apply any
       
   187                 // reviver function, and return
       
   188                 return _revive( eval('(' + s + ')'), reviver );
       
   189             }
       
   190         }
       
   191 
       
   192         throw new SyntaxError('JSON.parse');
       
   193     };
       
   194     
       
   195 Y.namespace('JSON').parse = function (s,reviver) {
       
   196     return Native && Y.JSON.useNativeParse ?
       
   197         Native.parse(s,reviver) : _parse(s,reviver);
       
   198 };
       
   199 
       
   200 /**
       
   201  * Leverage native JSON parse if the browser has a native implementation.
       
   202  * In general, this is a good idea.  See the Known Issues section in the
       
   203  * JSON user guide for caveats.  The default value is true for browsers with
       
   204  * native JSON support.
       
   205  *
       
   206  * @property useNativeParse
       
   207  * @type Boolean
       
   208  * @default true
       
   209  * @static
       
   210  */
       
   211 Y.JSON.useNativeParse = !!Native;
       
   212 
       
   213 
       
   214 }, '3.0.0' );
       
   215 YUI.add('json-stringify', function(Y) {
       
   216 
       
   217 /**
       
   218  * Provides Y.JSON.stringify method for converting objects to JSON strings.
       
   219  *
       
   220  * @module json
       
   221  * @submodule json-stringify
       
   222  * @for JSON
       
   223  * @static
       
   224  */
       
   225 var _JSON     = Y.config.win.JSON,
       
   226     Lang      = Y.Lang,
       
   227     isFunction= Lang.isFunction,
       
   228     isObject  = Lang.isObject,
       
   229     isArray   = Lang.isArray,
       
   230     _toStr    = Object.prototype.toString,
       
   231     Native    = (_toStr.call(_JSON) === '[object JSON]' && _JSON),
       
   232     UNDEFINED = 'undefined',
       
   233     OBJECT    = 'object',
       
   234     NULL      = 'null',
       
   235     STRING    = 'string',
       
   236     NUMBER    = 'number',
       
   237     BOOLEAN   = 'boolean',
       
   238     DATE      = 'date',
       
   239     _allowable= {
       
   240         'undefined'        : UNDEFINED,
       
   241         'string'           : STRING,
       
   242         '[object String]'  : STRING,
       
   243         'number'           : NUMBER,
       
   244         '[object Number]'  : NUMBER,
       
   245         'boolean'          : BOOLEAN,
       
   246         '[object Boolean]' : BOOLEAN,
       
   247         '[object Date]'    : DATE,
       
   248         '[object RegExp]'  : OBJECT
       
   249     },
       
   250     EMPTY     = '',
       
   251     OPEN_O    = '{',
       
   252     CLOSE_O   = '}',
       
   253     OPEN_A    = '[',
       
   254     CLOSE_A   = ']',
       
   255     COMMA     = ',',
       
   256     COMMA_CR  = ",\n",
       
   257     CR        = "\n",
       
   258     COLON     = ':',
       
   259     COLON_SP  = ': ',
       
   260     QUOTE     = '"',
       
   261     // Regex used to capture characters that need escaping before enclosing
       
   262     // their containing string in quotes.
       
   263     _SPECIAL_CHARS = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
       
   264     // Character substitution map for common escapes and special characters.
       
   265     _CHARS = {
       
   266         '\b': '\\b',
       
   267         '\t': '\\t',
       
   268         '\n': '\\n',
       
   269         '\f': '\\f',
       
   270         '\r': '\\r',
       
   271         '"' : '\\"',
       
   272         '\\': '\\\\'
       
   273     };
       
   274 
       
   275 
       
   276 // Utility function used to determine how to serialize a variable.
       
   277 function _type(o) {
       
   278     var t = typeof o;
       
   279     return  _allowable[t] ||              // number, string, boolean, undefined
       
   280             _allowable[_toStr.call(o)] || // Number, String, Boolean, Date
       
   281             (t === OBJECT ?
       
   282                 (o ? OBJECT : NULL) :     // object, array, null, misc natives
       
   283                 UNDEFINED);               // function, unknown
       
   284 }
       
   285 
       
   286 // Escapes a special character to a safe Unicode representation
       
   287 function _char(c) {
       
   288     if (!_CHARS[c]) {
       
   289         _CHARS[c] =  '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
       
   290     }
       
   291     return _CHARS[c];
       
   292 }
       
   293 
       
   294 // Enclose escaped strings in quotes
       
   295 function _string(s) {
       
   296     return QUOTE + s.replace(_SPECIAL_CHARS, _char) + QUOTE;
       
   297 }
       
   298 
       
   299 // Adds the provided space to the beginning of every line in the input string
       
   300 function _indent(s,space) {
       
   301     return s.replace(/^/gm, space);
       
   302 }
       
   303 
       
   304 // JavaScript implementation of stringify (see API declaration of stringify)
       
   305 function _stringify(o,w,space) {
       
   306     if (o === undefined) {
       
   307         return undefined;
       
   308     }
       
   309 
       
   310     var replacer = isFunction(w) ? w : null,
       
   311         format   = _toStr.call(space).match(/String|Number/) || [],
       
   312         _date    = Y.JSON.dateToString,
       
   313         stack    = [],
       
   314         tmp,i,len;
       
   315 
       
   316     if (replacer || !isArray(w)) {
       
   317         w = undefined;
       
   318     }
       
   319 
       
   320     // Ensure whitelist keys are unique (bug 2110391)
       
   321     if (w) {
       
   322         tmp = {};
       
   323         for (i = 0, len = w.length; i < len; ++i) {
       
   324             tmp[w[i]] = true;
       
   325         }
       
   326         w = tmp;
       
   327     }
       
   328 
       
   329     // Per the spec, strings are truncated to 10 characters and numbers
       
   330     // are converted to that number of spaces (max 10)
       
   331     space = format[0] === 'Number' ?
       
   332                 new Array(Math.min(Math.max(0,space),10)+1).join(" ") :
       
   333                 (space || EMPTY).slice(0,10);
       
   334 
       
   335     function _serialize(h,key) {
       
   336         var value = h[key],
       
   337             t     = _type(value),
       
   338             a     = [],
       
   339             colon = space ? COLON_SP : COLON,
       
   340             arr, i, keys, k, v;
       
   341 
       
   342         // Per the ECMA 5 spec, toJSON is applied before the replacer is
       
   343         // called.  Also per the spec, Date.prototype.toJSON has been added, so
       
   344         // Date instances should be serialized prior to exposure to the
       
   345         // replacer.  I disagree with this decision, but the spec is the spec.
       
   346         if (isObject(value) && isFunction(value.toJSON)) {
       
   347             value = value.toJSON(key);
       
   348         } else if (t === DATE) {
       
   349             value = _date(value);
       
   350         }
       
   351 
       
   352         if (isFunction(replacer)) {
       
   353             value = replacer.call(h,key,value);
       
   354         }
       
   355 
       
   356         if (value !== h[key]) {
       
   357             t = _type(value);
       
   358         }
       
   359 
       
   360         switch (t) {
       
   361             case DATE    : // intentional fallthrough.  Pre-replacer Dates are
       
   362                            // serialized in the toJSON stage.  Dates here would
       
   363                            // have been produced by the replacer.
       
   364             case OBJECT  : break;
       
   365             case STRING  : return _string(value);
       
   366             case NUMBER  : return isFinite(value) ? value+EMPTY : NULL;
       
   367             case BOOLEAN : return value+EMPTY;
       
   368             case NULL    : return NULL;
       
   369             default      : return undefined;
       
   370         }
       
   371 
       
   372         // Check for cyclical references in nested objects
       
   373         for (i = stack.length - 1; i >= 0; --i) {
       
   374             if (stack[i] === value) {
       
   375                 throw new Error("JSON.stringify. Cyclical reference");
       
   376             }
       
   377         }
       
   378 
       
   379         arr = isArray(value);
       
   380 
       
   381         // Add the object to the processing stack
       
   382         stack.push(value);
       
   383 
       
   384         if (arr) { // Array
       
   385             for (i = value.length - 1; i >= 0; --i) {
       
   386                 a[i] = _serialize(value, i) || NULL;
       
   387             }
       
   388         } else {   // Object
       
   389             // If whitelist provided, take only those keys
       
   390             keys = w || value;
       
   391             i = 0;
       
   392 
       
   393             for (k in keys) {
       
   394                 if (keys.hasOwnProperty(k)) {
       
   395                     v = _serialize(value, k);
       
   396                     if (v) {
       
   397                         a[i++] = _string(k) + colon + v;
       
   398                     }
       
   399                 }
       
   400             }
       
   401         }
       
   402 
       
   403         // remove the array from the stack
       
   404         stack.pop();
       
   405 
       
   406         if (space && a.length) {
       
   407             return arr ?
       
   408                 OPEN_A + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_A :
       
   409                 OPEN_O + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_O;
       
   410         } else {
       
   411             return arr ?
       
   412                 OPEN_A + a.join(COMMA) + CLOSE_A :
       
   413                 OPEN_O + a.join(COMMA) + CLOSE_O;
       
   414         }
       
   415     }
       
   416 
       
   417     // process the input
       
   418     return _serialize({'':o},'');
       
   419 }
       
   420 
       
   421 Y.mix(Y.namespace('JSON'),{
       
   422     /**
       
   423      * Leverage native JSON stringify if the browser has a native
       
   424      * implementation.  In general, this is a good idea.  See the Known Issues
       
   425      * section in the JSON user guide for caveats.  The default value is true
       
   426      * for browsers with native JSON support.
       
   427      *
       
   428      * @property JSON.useNativeStringify
       
   429      * @type Boolean
       
   430      * @default true
       
   431      * @static
       
   432      */
       
   433     useNativeStringify : !!Native,
       
   434 
       
   435     /**
       
   436      * Serializes a Date instance as a UTC date string.  Used internally by
       
   437      * stringify.  Override this method if you need Dates serialized in a
       
   438      * different format.
       
   439      *
       
   440      * @method dateToString
       
   441      * @param d {Date} The Date to serialize
       
   442      * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ
       
   443      * @static
       
   444      */
       
   445     dateToString : function (d) {
       
   446         function _zeroPad(v) {
       
   447             return v < 10 ? '0' + v : v;
       
   448         }
       
   449 
       
   450         return d.getUTCFullYear()           + '-' +
       
   451               _zeroPad(d.getUTCMonth() + 1) + '-' +
       
   452               _zeroPad(d.getUTCDate())      + 'T' +
       
   453               _zeroPad(d.getUTCHours())     + COLON +
       
   454               _zeroPad(d.getUTCMinutes())   + COLON +
       
   455               _zeroPad(d.getUTCSeconds())   + 'Z';
       
   456     },
       
   457 
       
   458     /**
       
   459      * <p>Converts an arbitrary value to a JSON string representation.</p>
       
   460      *
       
   461      * <p>Objects with cyclical references will trigger an exception.</p>
       
   462      *
       
   463      * <p>If a whitelist is provided, only matching object keys will be
       
   464      * included.  Alternately, a replacer function may be passed as the
       
   465      * second parameter.  This function is executed on every value in the
       
   466      * input, and its return value will be used in place of the original value.
       
   467      * This is useful to serialize specialized objects or class instances.</p>
       
   468      *
       
   469      * <p>If a positive integer or non-empty string is passed as the third
       
   470      * parameter, the output will be formatted with carriage returns and
       
   471      * indentation for readability.  If a String is passed (such as "\t") it
       
   472      * will be used once for each indentation level.  If a number is passed,
       
   473      * that number of spaces will be used.</p>
       
   474      *
       
   475      * @method stringify
       
   476      * @param o {MIXED} any arbitrary value to convert to JSON string
       
   477      * @param w {Array|Function} (optional) whitelist of acceptable object
       
   478      *                  keys to include, or a replacer function to modify the
       
   479      *                  raw value before serialization
       
   480      * @param ind {Number|String} (optional) indentation character or depth of
       
   481      *                  spaces to format the output.
       
   482      * @return {string} JSON string representation of the input
       
   483      * @static
       
   484      */
       
   485     stringify : function (o,w,ind) {
       
   486         return Native && Y.JSON.useNativeStringify ?
       
   487             Native.stringify(o,w,ind) : _stringify(o,w,ind);
       
   488     }
       
   489 });
       
   490 
       
   491 
       
   492 }, '3.0.0' );
       
   493 
       
   494 
       
   495 YUI.add('json', function(Y){}, '3.0.0' ,{use:['json-parse', 'json-stringify']});
       
   496