[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/ -> json2.js (source)

   1  /*
   2      json2.js
   3      2015-05-03
   4  
   5      Public Domain.
   6  
   7      NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
   8  
   9      See http://www.JSON.org/js.html
  10  
  11  
  12      This code should be minified before deployment.
  13      See http://javascript.crockford.com/jsmin.html
  14  
  15      USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
  16      NOT CONTROL.
  17  
  18  
  19      This file creates a global JSON object containing two methods: stringify
  20      and parse. This file is provides the ES5 JSON capability to ES3 systems.
  21      If a project might run on IE8 or earlier, then this file should be included.
  22      This file does nothing on ES5 systems.
  23  
  24          JSON.stringify(value, replacer, space)
  25              value       any JavaScript value, usually an object or array.
  26  
  27              replacer    an optional parameter that determines how object
  28                          values are stringified for objects. It can be a
  29                          function or an array of strings.
  30  
  31              space       an optional parameter that specifies the indentation
  32                          of nested structures. If it is omitted, the text will
  33                          be packed without extra whitespace. If it is a number,
  34                          it will specify the number of spaces to indent at each
  35                          level. If it is a string (such as '\t' or ' '),
  36                          it contains the characters used to indent at each level.
  37  
  38              This method produces a JSON text from a JavaScript value.
  39  
  40              When an object value is found, if the object contains a toJSON
  41              method, its toJSON method will be called and the result will be
  42              stringified. A toJSON method does not serialize: it returns the
  43              value represented by the name/value pair that should be serialized,
  44              or undefined if nothing should be serialized. The toJSON method
  45              will be passed the key associated with the value, and this will be
  46              bound to the value
  47  
  48              For example, this would serialize Dates as ISO strings.
  49  
  50                  Date.prototype.toJSON = function (key) {
  51                      function f(n) {
  52                          // Format integers to have at least two digits.
  53                          return n < 10 
  54                              ? '0' + n 
  55                              : n;
  56                      }
  57  
  58                      return this.getUTCFullYear()   + '-' +
  59                           f(this.getUTCMonth() + 1) + '-' +
  60                           f(this.getUTCDate())      + 'T' +
  61                           f(this.getUTCHours())     + ':' +
  62                           f(this.getUTCMinutes())   + ':' +
  63                           f(this.getUTCSeconds())   + 'Z';
  64                  };
  65  
  66              You can provide an optional replacer method. It will be passed the
  67              key and value of each member, with this bound to the containing
  68              object. The value that is returned from your method will be
  69              serialized. If your method returns undefined, then the member will
  70              be excluded from the serialization.
  71  
  72              If the replacer parameter is an array of strings, then it will be
  73              used to select the members to be serialized. It filters the results
  74              such that only members with keys listed in the replacer array are
  75              stringified.
  76  
  77              Values that do not have JSON representations, such as undefined or
  78              functions, will not be serialized. Such values in objects will be
  79              dropped; in arrays they will be replaced with null. You can use
  80              a replacer function to replace those with JSON values.
  81              JSON.stringify(undefined) returns undefined.
  82  
  83              The optional space parameter produces a stringification of the
  84              value that is filled with line breaks and indentation to make it
  85              easier to read.
  86  
  87              If the space parameter is a non-empty string, then that string will
  88              be used for indentation. If the space parameter is a number, then
  89              the indentation will be that many spaces.
  90  
  91              Example:
  92  
  93              text = JSON.stringify(['e', {pluribus: 'unum'}]);
  94              // text is '["e",{"pluribus":"unum"}]'
  95  
  96  
  97              text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
  98              // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
  99  
 100              text = JSON.stringify([new Date()], function (key, value) {
 101                  return this[key] instanceof Date 
 102                      ? 'Date(' + this[key] + ')' 
 103                      : value;
 104              });
 105              // text is '["Date(---current time---)"]'
 106  
 107  
 108          JSON.parse(text, reviver)
 109              This method parses a JSON text to produce an object or array.
 110              It can throw a SyntaxError exception.
 111  
 112              The optional reviver parameter is a function that can filter and
 113              transform the results. It receives each of the keys and values,
 114              and its return value is used instead of the original value.
 115              If it returns what it received, then the structure is not modified.
 116              If it returns undefined then the member is deleted.
 117  
 118              Example:
 119  
 120              // Parse the text. Values that look like ISO date strings will
 121              // be converted to Date objects.
 122  
 123              myData = JSON.parse(text, function (key, value) {
 124                  var a;
 125                  if (typeof value === 'string') {
 126                      a =
 127  /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
 128                      if (a) {
 129                          return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
 130                              +a[5], +a[6]));
 131                      }
 132                  }
 133                  return value;
 134              });
 135  
 136              myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
 137                  var d;
 138                  if (typeof value === 'string' &&
 139                          value.slice(0, 5) === 'Date(' &&
 140                          value.slice(-1) === ')') {
 141                      d = new Date(value.slice(5, -1));
 142                      if (d) {
 143                          return d;
 144                      }
 145                  }
 146                  return value;
 147              });
 148  
 149  
 150      This is a reference implementation. You are free to copy, modify, or
 151      redistribute.
 152  */
 153  
 154  /*jslint 
 155      eval, for, this 
 156  */
 157  
 158  /*property
 159      JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
 160      getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
 161      lastIndex, length, parse, prototype, push, replace, slice, stringify,
 162      test, toJSON, toString, valueOf
 163  */
 164  
 165  
 166  // Create a JSON object only if one does not already exist. We create the
 167  // methods in a closure to avoid creating global variables.
 168  
 169  if (typeof JSON !== 'object') {
 170      JSON = {};
 171  }
 172  
 173  (function () {
 174      'use strict';
 175      
 176      var rx_one = /^[\],:{}\s]*$/,
 177          rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
 178          rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
 179          rx_four = /(?:^|:|,)(?:\s*\[)+/g,
 180          rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
 181          rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
 182  
 183      function f(n) {
 184          // Format integers to have at least two digits.
 185          return n < 10 
 186              ? '0' + n 
 187              : n;
 188      }
 189      
 190      function this_value() {
 191          return this.valueOf();
 192      }
 193  
 194      if (typeof Date.prototype.toJSON !== 'function') {
 195  
 196          Date.prototype.toJSON = function () {
 197  
 198              return isFinite(this.valueOf())
 199                  ? this.getUTCFullYear() + '-' +
 200                          f(this.getUTCMonth() + 1) + '-' +
 201                          f(this.getUTCDate()) + 'T' +
 202                          f(this.getUTCHours()) + ':' +
 203                          f(this.getUTCMinutes()) + ':' +
 204                          f(this.getUTCSeconds()) + 'Z'
 205                  : null;
 206          };
 207  
 208          Boolean.prototype.toJSON = this_value;
 209          Number.prototype.toJSON = this_value;
 210          String.prototype.toJSON = this_value;
 211      }
 212  
 213      var gap,
 214          indent,
 215          meta,
 216          rep;
 217  
 218  
 219      function quote(string) {
 220  
 221  // If the string contains no control characters, no quote characters, and no
 222  // backslash characters, then we can safely slap some quotes around it.
 223  // Otherwise we must also replace the offending characters with safe escape
 224  // sequences.
 225  
 226          rx_escapable.lastIndex = 0;
 227          return rx_escapable.test(string) 
 228              ? '"' + string.replace(rx_escapable, function (a) {
 229                  var c = meta[a];
 230                  return typeof c === 'string'
 231                      ? c
 232                      : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 233              }) + '"' 
 234              : '"' + string + '"';
 235      }
 236  
 237  
 238      function str(key, holder) {
 239  
 240  // Produce a string from holder[key].
 241  
 242          var i,          // The loop counter.
 243              k,          // The member key.
 244              v,          // The member value.
 245              length,
 246              mind = gap,
 247              partial,
 248              value = holder[key];
 249  
 250  // If the value has a toJSON method, call it to obtain a replacement value.
 251  
 252          if (value && typeof value === 'object' &&
 253                  typeof value.toJSON === 'function') {
 254              value = value.toJSON(key);
 255          }
 256  
 257  // If we were called with a replacer function, then call the replacer to
 258  // obtain a replacement value.
 259  
 260          if (typeof rep === 'function') {
 261              value = rep.call(holder, key, value);
 262          }
 263  
 264  // What happens next depends on the value's type.
 265  
 266          switch (typeof value) {
 267          case 'string':
 268              return quote(value);
 269  
 270          case 'number':
 271  
 272  // JSON numbers must be finite. Encode non-finite numbers as null.
 273  
 274              return isFinite(value) 
 275                  ? String(value) 
 276                  : 'null';
 277  
 278          case 'boolean':
 279          case 'null':
 280  
 281  // If the value is a boolean or null, convert it to a string. Note:
 282  // typeof null does not produce 'null'. The case is included here in
 283  // the remote chance that this gets fixed someday.
 284  
 285              return String(value);
 286  
 287  // If the type is 'object', we might be dealing with an object or an array or
 288  // null.
 289  
 290          case 'object':
 291  
 292  // Due to a specification blunder in ECMAScript, typeof null is 'object',
 293  // so watch out for that case.
 294  
 295              if (!value) {
 296                  return 'null';
 297              }
 298  
 299  // Make an array to hold the partial results of stringifying this object value.
 300  
 301              gap += indent;
 302              partial = [];
 303  
 304  // Is the value an array?
 305  
 306              if (Object.prototype.toString.apply(value) === '[object Array]') {
 307  
 308  // The value is an array. Stringify every element. Use null as a placeholder
 309  // for non-JSON values.
 310  
 311                  length = value.length;
 312                  for (i = 0; i < length; i += 1) {
 313                      partial[i] = str(i, value) || 'null';
 314                  }
 315  
 316  // Join all of the elements together, separated with commas, and wrap them in
 317  // brackets.
 318  
 319                  v = partial.length === 0
 320                      ? '[]'
 321                      : gap
 322                          ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
 323                          : '[' + partial.join(',') + ']';
 324                  gap = mind;
 325                  return v;
 326              }
 327  
 328  // If the replacer is an array, use it to select the members to be stringified.
 329  
 330              if (rep && typeof rep === 'object') {
 331                  length = rep.length;
 332                  for (i = 0; i < length; i += 1) {
 333                      if (typeof rep[i] === 'string') {
 334                          k = rep[i];
 335                          v = str(k, value);
 336                          if (v) {
 337                              partial.push(quote(k) + (
 338                                  gap 
 339                                      ? ': ' 
 340                                      : ':'
 341                              ) + v);
 342                          }
 343                      }
 344                  }
 345              } else {
 346  
 347  // Otherwise, iterate through all of the keys in the object.
 348  
 349                  for (k in value) {
 350                      if (Object.prototype.hasOwnProperty.call(value, k)) {
 351                          v = str(k, value);
 352                          if (v) {
 353                              partial.push(quote(k) + (
 354                                  gap 
 355                                      ? ': ' 
 356                                      : ':'
 357                              ) + v);
 358                          }
 359                      }
 360                  }
 361              }
 362  
 363  // Join all of the member texts together, separated with commas,
 364  // and wrap them in braces.
 365  
 366              v = partial.length === 0
 367                  ? '{}'
 368                  : gap
 369                      ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
 370                      : '{' + partial.join(',') + '}';
 371              gap = mind;
 372              return v;
 373          }
 374      }
 375  
 376  // If the JSON object does not yet have a stringify method, give it one.
 377  
 378      if (typeof JSON.stringify !== 'function') {
 379          meta = {    // table of character substitutions
 380              '\b': '\\b',
 381              '\t': '\\t',
 382              '\n': '\\n',
 383              '\f': '\\f',
 384              '\r': '\\r',
 385              '"': '\\"',
 386              '\\': '\\\\'
 387          };
 388          JSON.stringify = function (value, replacer, space) {
 389  
 390  // The stringify method takes a value and an optional replacer, and an optional
 391  // space parameter, and returns a JSON text. The replacer can be a function
 392  // that can replace values, or an array of strings that will select the keys.
 393  // A default replacer method can be provided. Use of the space parameter can
 394  // produce text that is more easily readable.
 395  
 396              var i;
 397              gap = '';
 398              indent = '';
 399  
 400  // If the space parameter is a number, make an indent string containing that
 401  // many spaces.
 402  
 403              if (typeof space === 'number') {
 404                  for (i = 0; i < space; i += 1) {
 405                      indent += ' ';
 406                  }
 407  
 408  // If the space parameter is a string, it will be used as the indent string.
 409  
 410              } else if (typeof space === 'string') {
 411                  indent = space;
 412              }
 413  
 414  // If there is a replacer, it must be a function or an array.
 415  // Otherwise, throw an error.
 416  
 417              rep = replacer;
 418              if (replacer && typeof replacer !== 'function' &&
 419                      (typeof replacer !== 'object' ||
 420                      typeof replacer.length !== 'number')) {
 421                  throw new Error('JSON.stringify');
 422              }
 423  
 424  // Make a fake root object containing our value under the key of ''.
 425  // Return the result of stringifying the value.
 426  
 427              return str('', {'': value});
 428          };
 429      }
 430  
 431  
 432  // If the JSON object does not yet have a parse method, give it one.
 433  
 434      if (typeof JSON.parse !== 'function') {
 435          JSON.parse = function (text, reviver) {
 436  
 437  // The parse method takes a text and an optional reviver function, and returns
 438  // a JavaScript value if the text is a valid JSON text.
 439  
 440              var j;
 441  
 442              function walk(holder, key) {
 443  
 444  // The walk method is used to recursively walk the resulting structure so
 445  // that modifications can be made.
 446  
 447                  var k, v, value = holder[key];
 448                  if (value && typeof value === 'object') {
 449                      for (k in value) {
 450                          if (Object.prototype.hasOwnProperty.call(value, k)) {
 451                              v = walk(value, k);
 452                              if (v !== undefined) {
 453                                  value[k] = v;
 454                              } else {
 455                                  delete value[k];
 456                              }
 457                          }
 458                      }
 459                  }
 460                  return reviver.call(holder, key, value);
 461              }
 462  
 463  
 464  // Parsing happens in four stages. In the first stage, we replace certain
 465  // Unicode characters with escape sequences. JavaScript handles many characters
 466  // incorrectly, either silently deleting them, or treating them as line endings.
 467  
 468              text = String(text);
 469              rx_dangerous.lastIndex = 0;
 470              if (rx_dangerous.test(text)) {
 471                  text = text.replace(rx_dangerous, function (a) {
 472                      return '\\u' +
 473                              ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 474                  });
 475              }
 476  
 477  // In the second stage, we run the text against regular expressions that look
 478  // for non-JSON patterns. We are especially concerned with '()' and 'new'
 479  // because they can cause invocation, and '=' because it can cause mutation.
 480  // But just to be safe, we want to reject all unexpected forms.
 481  
 482  // We split the second stage into 4 regexp operations in order to work around
 483  // crippling inefficiencies in IE's and Safari's regexp engines. First we
 484  // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
 485  // replace all simple value tokens with ']' characters. Third, we delete all
 486  // open brackets that follow a colon or comma or that begin the text. Finally,
 487  // we look to see that the remaining characters are only whitespace or ']' or
 488  // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
 489  
 490              if (
 491                  rx_one.test(
 492                      text
 493                          .replace(rx_two, '@')
 494                          .replace(rx_three, ']')
 495                          .replace(rx_four, '')
 496                  )
 497              ) {
 498  
 499  // In the third stage we use the eval function to compile the text into a
 500  // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
 501  // in JavaScript: it can begin a block or an object literal. We wrap the text
 502  // in parens to eliminate the ambiguity.
 503  
 504                  j = eval('(' + text + ')');
 505  
 506  // In the optional fourth stage, we recursively walk the new structure, passing
 507  // each name/value pair to a reviver function for possible transformation.
 508  
 509                  return typeof reviver === 'function'
 510                      ? walk({'': j}, '')
 511                      : j;
 512              }
 513  
 514  // If the text is not JSON parseable, then a SyntaxError is thrown.
 515  
 516              throw new SyntaxError('JSON.parse');
 517          };
 518      }
 519  }());


Generated : Thu Apr 25 08:20:02 2024 Cross-referenced by PHPXref