src/cm/media/js/lib/yui/yui_3.0.0b1/build/json/json-stringify-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.0b1
       
     6 build: 1163
       
     7 */
       
     8 YUI.add('json-stringify', function(Y) {
       
     9 
       
    10 /**
       
    11  * Provides Y.JSON.stringify method for converting objects to JSON strings.
       
    12  *
       
    13  * @module json
       
    14  * @submodule json-stringify
       
    15  * @for JSON
       
    16  * @static
       
    17  */
       
    18 var _toString = Object.prototype.toString,
       
    19     Lang      = Y.Lang,
       
    20     isFunction= Lang.isFunction,
       
    21     isArray   = Lang.isArray,
       
    22     type      = Lang.type,
       
    23     STRING    = 'string',
       
    24     NUMBER    = 'number',
       
    25     BOOLEAN   = 'boolean',
       
    26     OBJECT    = 'object',
       
    27     ARRAY     = 'array',
       
    28     REGEXP    = 'regexp',
       
    29     ERROR     = 'error',
       
    30     NULL      = 'null',
       
    31     DATE      = 'date',
       
    32     EMPTY     = '',
       
    33     OPEN_O    = '{',
       
    34     CLOSE_O   = '}',
       
    35     OPEN_A    = '[',
       
    36     CLOSE_A   = ']',
       
    37     COMMA     = ',',
       
    38     COMMA_CR  = ",\n",
       
    39     CR        = "\n",
       
    40     COLON     = ':',
       
    41     COLON_SP  = ': ',
       
    42     QUOTE     = '"';
       
    43 
       
    44 Y.mix(Y.namespace('JSON'),{
       
    45     /**
       
    46      * Regex used to capture characters that need escaping before enclosing
       
    47      * their containing string in quotes.
       
    48      *
       
    49      * @property _SPECIAL_CHARS
       
    50      * @type {RegExp}
       
    51      * @protected
       
    52      */
       
    53     _SPECIAL_CHARS : /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
       
    54 
       
    55     /**
       
    56      * Character substitution map for common escapes and special characters.
       
    57      *
       
    58      * @property _CHARS
       
    59      * @type {Object}
       
    60      * @static
       
    61      * @protected
       
    62      */
       
    63     _CHARS : {
       
    64         '\b': '\\b',
       
    65         '\t': '\\t',
       
    66         '\n': '\\n',
       
    67         '\f': '\\f',
       
    68         '\r': '\\r',
       
    69         '"' : '\\"',
       
    70         '\\': '\\\\'
       
    71     },
       
    72 
       
    73     /**
       
    74      * Serializes a Date instance as a UTC date string.  Used internally by
       
    75      * stringify.  Override this method if you need Dates serialized in a
       
    76      * different format.
       
    77      *
       
    78      * @method dateToString
       
    79      * @param d {Date} The Date to serialize
       
    80      * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ
       
    81      * @static
       
    82      */
       
    83     dateToString : function (d) {
       
    84         function _zeroPad(v) {
       
    85             return v < 10 ? '0' + v : v;
       
    86         }
       
    87 
       
    88         return QUOTE + d.getUTCFullYear()   + '-' +
       
    89               _zeroPad(d.getUTCMonth() + 1) + '-' +
       
    90               _zeroPad(d.getUTCDate())      + 'T' +
       
    91               _zeroPad(d.getUTCHours())     + COLON +
       
    92               _zeroPad(d.getUTCMinutes())   + COLON +
       
    93               _zeroPad(d.getUTCSeconds())   + 'Z' + QUOTE;
       
    94     },
       
    95 
       
    96     /**
       
    97      * <p>Converts an arbitrary value to a JSON string representation.</p>
       
    98      *
       
    99      * <p>Objects with cyclical references will trigger an exception.</p>
       
   100      *
       
   101      * <p>If a whitelist is provided, only matching object keys will be
       
   102      * included.  Alternately, a replacer function may be passed as the
       
   103      * second parameter.  This function is executed on every value in the
       
   104      * input, and its return value will be used in place of the original value.
       
   105      * This is useful to serialize specialized objects or class instances.</p>
       
   106      *
       
   107      * <p>If a positive integer or non-empty string is passed as the third
       
   108      * parameter, the output will be formatted with carriage returns and
       
   109      * indentation for readability.  If a String is passed (such as "\t") it
       
   110      * will be used once for each indentation level.  If a number is passed,
       
   111      * that number of spaces will be used.</p>
       
   112      *
       
   113      * @method stringify
       
   114      * @param o {MIXED} any arbitrary value to convert to JSON string
       
   115      * @param w {Array|Function} (optional) whitelist of acceptable object
       
   116      *                  keys to include, or a replacer function to modify the
       
   117      *                  raw value before serialization
       
   118      * @param ind {Number|String} (optional) indentation character or depth of
       
   119      *                  spaces to format the output.
       
   120      * @return {string} JSON string representation of the input
       
   121      * @static
       
   122      */
       
   123     stringify : function (o,w,ind) {
       
   124 
       
   125         var m      = Y.JSON._CHARS,
       
   126             str_re = Y.JSON._SPECIAL_CHARS,
       
   127             rep    = isFunction(w) ? w : null,
       
   128             pstack = [], // Processing stack used for cyclical ref protection
       
   129             _date  = Y.JSON.dateToString, // Use configured date serialization
       
   130             format = _toString.call(ind).match(/String|Number/);
       
   131 
       
   132         if (rep || typeof w !== 'object') {
       
   133             w = undefined;
       
   134         }
       
   135 
       
   136         if (format) {
       
   137             // String instances and primatives are left alone.  String objects
       
   138             // coerce for the indenting operations.
       
   139             if (format[0] === 'Number') {
       
   140 
       
   141                 // force numeric indent values between {0,100} per the spec
       
   142                 // This also converts Number instances to primative
       
   143                 ind = new Array(Math.min(Math.max(0,ind),100)+1).join(" ");
       
   144             }
       
   145 
       
   146             // turn off formatting for 0 or empty string
       
   147             format = ind;
       
   148         }
       
   149 
       
   150         // escape encode special characters
       
   151         function _char(c) {
       
   152             if (!m[c]) {
       
   153                 m[c]='\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
       
   154             }
       
   155             return m[c];
       
   156         }
       
   157 
       
   158         // Enclose the escaped string in double quotes
       
   159         function _string(s) {
       
   160             return QUOTE + s.replace(str_re, _char) + QUOTE;
       
   161         }
       
   162 
       
   163         // Check for cyclical references
       
   164         function _cyclicalTest(o) {
       
   165             for (var i = pstack.length - 1; i >= 0; --i) {
       
   166                 if (pstack[i] === o) {
       
   167                     throw new Error("JSON.stringify. Cyclical reference");
       
   168                 }
       
   169             }
       
   170             return false;
       
   171         }
       
   172 
       
   173         function _indent(s) {
       
   174             return s.replace(/^/gm,ind);
       
   175         }
       
   176 
       
   177         function _object(o,arr) {
       
   178             // Add the object to the processing stack
       
   179             pstack.push(o);
       
   180 
       
   181             var a = [],
       
   182                 colon = format ? COLON_SP : COLON,
       
   183                 i, j, len, k, v;
       
   184 
       
   185             if (arr) { // Array
       
   186                 for (i = o.length - 1; i >= 0; --i) {
       
   187                     a[i] = _stringify(o,i) || NULL;
       
   188                 }
       
   189             } else {   // Object
       
   190                 // If whitelist provided, take only those keys
       
   191                 k = isArray(w) ? w : Y.Object.keys(o);
       
   192 
       
   193                 for (i = 0, j = 0, len = k.length; i < len; ++i) {
       
   194                     if (typeof k[i] === STRING) {
       
   195                         v = _stringify(o,k[i]);
       
   196                         if (v) {
       
   197                             a[j++] = _string(k[i]) + colon + v;
       
   198                         }
       
   199                     }
       
   200                 }
       
   201             }
       
   202 
       
   203             // remove the array from the stack
       
   204             pstack.pop();
       
   205 
       
   206             if (format && a.length) {
       
   207                 return arr ?
       
   208                     OPEN_A + CR + _indent(a.join(COMMA_CR)) + CR + CLOSE_A :
       
   209                     OPEN_O + CR + _indent(a.join(COMMA_CR)) + CR + CLOSE_O;
       
   210             } else {
       
   211                 return arr ?
       
   212                     OPEN_A + a.join(COMMA) + CLOSE_A :
       
   213                     OPEN_O + a.join(COMMA) + CLOSE_O;
       
   214             }
       
   215         }
       
   216 
       
   217         // Worker function.  Fork behavior on data type and recurse objects.
       
   218         function _stringify(h,key) {
       
   219             var o = isFunction(rep) ? rep.call(h,key,h[key]) : h[key],
       
   220                 t = type(o);
       
   221 
       
   222             if (t === OBJECT) {
       
   223                 if (/String|Number|Boolean/.test(_toString.call(o))) {
       
   224                     o = o.valueOf();
       
   225                     t = type(o);
       
   226                 }
       
   227             }
       
   228 
       
   229             switch (t) {
       
   230                 case STRING  : return _string(o);
       
   231                 case NUMBER  : return isFinite(o) ? o+EMPTY : NULL;
       
   232                 case BOOLEAN : return o+EMPTY;
       
   233                 case DATE    : return _date(o);
       
   234                 case NULL    : return NULL;
       
   235                 case ARRAY   : _cyclicalTest(o); return _object(o,true);
       
   236                 case REGEXP  : // intentional fall through
       
   237                 case ERROR   : // intentional fall through
       
   238                 case OBJECT  : _cyclicalTest(o); return _object(o);
       
   239                 default      : return undefined;
       
   240             }
       
   241         }
       
   242 
       
   243         // process the input
       
   244         return _stringify({'':o},EMPTY);
       
   245     }
       
   246 });
       
   247 
       
   248 
       
   249 }, '3.0.0b1' );