[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/json-stringify-shim/ -> json-stringify-shim.js (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1