src/cm/media/js/lib/yui/yui3-3.15.0/build/json-stringify-shim/json-stringify-shim-debug.js
changeset 602 e16a97fb364a
equal deleted inserted replaced
601:d334a616c023 602:e16a97fb364a
       
     1 YUI.add('json-stringify-shim', function (Y, NAME) {
       
     2 
       
     3 // All internals kept private for security reasons
       
     4 var Lang      = Y.Lang,
       
     5     isFunction= Lang.isFunction,
       
     6     isObject  = Lang.isObject,
       
     7     isArray   = Lang.isArray,
       
     8     _toStr    = Object.prototype.toString,
       
     9     UNDEFINED = 'undefined',
       
    10     OBJECT    = 'object',
       
    11     NULL      = 'null',
       
    12     STRING    = 'string',
       
    13     NUMBER    = 'number',
       
    14     BOOLEAN   = 'boolean',
       
    15     DATE      = 'date',
       
    16     _allowable= {
       
    17         'undefined'        : UNDEFINED,
       
    18         'string'           : STRING,
       
    19         '[object String]'  : STRING,
       
    20         'number'           : NUMBER,
       
    21         '[object Number]'  : NUMBER,
       
    22         'boolean'          : BOOLEAN,
       
    23         '[object Boolean]' : BOOLEAN,
       
    24         '[object Date]'    : DATE,
       
    25         '[object RegExp]'  : OBJECT
       
    26     },
       
    27     EMPTY     = '',
       
    28     OPEN_O    = '{',
       
    29     CLOSE_O   = '}',
       
    30     OPEN_A    = '[',
       
    31     CLOSE_A   = ']',
       
    32     COMMA     = ',',
       
    33     COMMA_CR  = ",\n",
       
    34     CR        = "\n",
       
    35     COLON     = ':',
       
    36     COLON_SP  = ': ',
       
    37     QUOTE     = '"',
       
    38 
       
    39     // Regex used to capture characters that need escaping before enclosing
       
    40     // their containing string in quotes.
       
    41     _SPECIAL = /[\x00-\x07\x0b\x0e-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
       
    42 
       
    43     // Character substitution map for common escapes and special characters.
       
    44     _COMMON = [
       
    45         [/\\/g, '\\\\'],
       
    46         [/\"/g, '\\"'],
       
    47         [/\x08/g, '\\b'],
       
    48         [/\x09/g, '\\t'],
       
    49         [/\x0a/g, '\\n'],
       
    50         [/\x0c/g, '\\f'],
       
    51         [/\x0d/g, '\\r']
       
    52     ],
       
    53     _COMMON_LENGTH = _COMMON.length,
       
    54 
       
    55     // In-process optimization for special character escapes that haven't yet
       
    56     // been promoted to _COMMON
       
    57     _CHAR = {},
       
    58 
       
    59     // Per-char counter to determine if it's worth fast tracking a special
       
    60     // character escape sequence.
       
    61     _CHAR_COUNT, _CACHE_THRESHOLD;
       
    62 
       
    63 // Utility function used to determine how to serialize a variable.
       
    64 function _type(o) {
       
    65     var t = typeof o;
       
    66     return  _allowable[t] ||              // number, string, boolean, undefined
       
    67             _allowable[_toStr.call(o)] || // Number, String, Boolean, Date
       
    68             (t === OBJECT ?
       
    69                 (o ? OBJECT : NULL) :     // object, array, null, misc natives
       
    70                 UNDEFINED);               // function, unknown
       
    71 }
       
    72 
       
    73 // Escapes a special character to a safe Unicode representation
       
    74 function _char(c) {
       
    75     if (!_CHAR[c]) {
       
    76         _CHAR[c] = '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
       
    77         _CHAR_COUNT[c] = 0;
       
    78     }
       
    79 
       
    80     // === to avoid this conditional for the remainder of the current operation
       
    81     if (++_CHAR_COUNT[c] === _CACHE_THRESHOLD) {
       
    82         _COMMON.push([new RegExp(c, 'g'), _CHAR[c]]);
       
    83         _COMMON_LENGTH = _COMMON.length;
       
    84     }
       
    85 
       
    86     return _CHAR[c];
       
    87 }
       
    88 
       
    89 // Enclose escaped strings in quotes
       
    90 function _string(s) {
       
    91     var i, chr;
       
    92 
       
    93     // Preprocess the string against common characters to avoid function
       
    94     // overhead associated with replacement via function.
       
    95     for (i = 0; i < _COMMON_LENGTH; i++) {
       
    96         chr = _COMMON[i];
       
    97         s = s.replace(chr[0], chr[1]);
       
    98     }
       
    99 
       
   100     // original function replace for the not-as-common set of chars
       
   101     return QUOTE + s.replace(_SPECIAL, _char) + QUOTE;
       
   102 }
       
   103 
       
   104 // Adds the provided space to the beginning of every line in the input string
       
   105 function _indent(s,space) {
       
   106     return s.replace(/^/gm, space);
       
   107 }
       
   108 
       
   109 Y.JSON.stringify = function _stringify(o,w,space) {
       
   110     if (o === undefined) {
       
   111         return undefined;
       
   112     }
       
   113 
       
   114     var replacer = isFunction(w) ? w : null,
       
   115         format   = _toStr.call(space).match(/String|Number/) || [],
       
   116         _date    = Y.JSON.dateToString,
       
   117         stack    = [],
       
   118         tmp,i,len;
       
   119 
       
   120     _CHAR_COUNT      = {};
       
   121     _CACHE_THRESHOLD = Y.JSON.charCacheThreshold;
       
   122 
       
   123     if (replacer || !isArray(w)) {
       
   124         w = undefined;
       
   125     }
       
   126 
       
   127     // Ensure whitelist keys are unique (bug 2110391)
       
   128     if (w) {
       
   129         tmp = {};
       
   130         for (i = 0, len = w.length; i < len; ++i) {
       
   131             tmp[w[i]] = true;
       
   132         }
       
   133         w = tmp;
       
   134     }
       
   135 
       
   136     // Per the spec, strings are truncated to 10 characters and numbers
       
   137     // are converted to that number of spaces (max 10)
       
   138     space = format[0] === 'Number' ?
       
   139                 new Array(Math.min(Math.max(0,space),10)+1).join(" ") :
       
   140                 (space || EMPTY).slice(0,10);
       
   141 
       
   142     function _serialize(h,key) {
       
   143         var value = h[key],
       
   144             t     = _type(value),
       
   145             a     = [],
       
   146             colon = space ? COLON_SP : COLON,
       
   147             arr, i, keys, k, v;
       
   148 
       
   149         // Per the ECMA 5 spec, toJSON is applied before the replacer is
       
   150         // called.  Also per the spec, Date.prototype.toJSON has been added, so
       
   151         // Date instances should be serialized prior to exposure to the
       
   152         // replacer.  I disagree with this decision, but the spec is the spec.
       
   153         if (isObject(value) && isFunction(value.toJSON)) {
       
   154             value = value.toJSON(key);
       
   155         } else if (t === DATE) {
       
   156             value = _date(value);
       
   157         }
       
   158 
       
   159         if (isFunction(replacer)) {
       
   160             value = replacer.call(h,key,value);
       
   161         }
       
   162 
       
   163         if (value !== h[key]) {
       
   164             t = _type(value);
       
   165         }
       
   166 
       
   167         switch (t) {
       
   168             case DATE    : // intentional fallthrough.  Pre-replacer Dates are
       
   169                            // serialized in the toJSON stage.  Dates here would
       
   170                            // have been produced by the replacer.
       
   171             case OBJECT  : break;
       
   172             case STRING  : return _string(value);
       
   173             case NUMBER  : return isFinite(value) ? value+EMPTY : NULL;
       
   174             case BOOLEAN : return value+EMPTY;
       
   175             case NULL    : return NULL;
       
   176             default      : return undefined;
       
   177         }
       
   178 
       
   179         // Check for cyclical references in nested objects
       
   180         for (i = stack.length - 1; i >= 0; --i) {
       
   181             if (stack[i] === value) {
       
   182                 throw new Error("JSON.stringify. Cyclical reference");
       
   183             }
       
   184         }
       
   185 
       
   186         arr = isArray(value);
       
   187 
       
   188         // Add the object to the processing stack
       
   189         stack.push(value);
       
   190 
       
   191         if (arr) { // Array
       
   192             for (i = value.length - 1; i >= 0; --i) {
       
   193                 a[i] = _serialize(value, i) || NULL;
       
   194             }
       
   195         } else {   // Object
       
   196             // If whitelist provided, take only those keys
       
   197             keys = w || value;
       
   198             i = 0;
       
   199 
       
   200             for (k in keys) {
       
   201                 if (keys.hasOwnProperty(k)) {
       
   202                     v = _serialize(value, k);
       
   203                     if (v) {
       
   204                         a[i++] = _string(k) + colon + v;
       
   205                     }
       
   206                 }
       
   207             }
       
   208         }
       
   209 
       
   210         // remove the array from the stack
       
   211         stack.pop();
       
   212 
       
   213         if (space && a.length) {
       
   214             return arr ?
       
   215                 OPEN_A + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_A :
       
   216                 OPEN_O + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_O;
       
   217         } else {
       
   218             return arr ?
       
   219                 OPEN_A + a.join(COMMA) + CLOSE_A :
       
   220                 OPEN_O + a.join(COMMA) + CLOSE_O;
       
   221         }
       
   222     }
       
   223 
       
   224     // process the input
       
   225     return _serialize({'':o},'');
       
   226 };
       
   227 
       
   228 // Property available for testing if the implementation being used
       
   229 // is native or a shim
       
   230 Y.JSON.stringify.isShim = true;
       
   231 
       
   232 
       
   233 }, '@VERSION@', {"requires": ["json-stringify"]});