[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('yui2-json', function(Y) { 2 var YAHOO = Y.YUI2; 3 /* 4 Copyright (c) 2011, Yahoo! Inc. All rights reserved. 5 Code licensed under the BSD License: 6 http://developer.yahoo.com/yui/license.html 7 version: 2.9.0 8 */ 9 /** 10 * Provides methods to parse JSON strings and convert objects to JSON strings. 11 * 12 * @module json 13 * @class JSON 14 * @namespace YAHOO.lang 15 * @static 16 */ 17 (function () { 18 19 var l = YAHOO.lang, 20 isFunction = l.isFunction, 21 isObject = l.isObject, 22 isArray = l.isArray, 23 _toStr = Object.prototype.toString, 24 // 'this' is the global object. window in browser env. Keep 25 // the code env agnostic. Caja requies window, unfortunately. 26 Native = (YAHOO.env.ua.caja ? window : this).JSON, 27 28 /* Variables used by parse */ 29 30 /** 31 * Replace certain Unicode characters that JavaScript may handle incorrectly 32 * during eval--either by deleting them or treating them as line 33 * endings--with escape sequences. 34 * IMPORTANT NOTE: This regex will be used to modify the input if a match is 35 * found. 36 * 37 * @property _UNICODE_EXCEPTIONS 38 * @type {RegExp} 39 * @private 40 */ 41 _UNICODE_EXCEPTIONS = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 42 43 /** 44 * First step in the safety evaluation. Regex used to replace all escape 45 * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character). 46 * 47 * @property _ESCAPES 48 * @type {RegExp} 49 * @static 50 * @private 51 */ 52 _ESCAPES = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, 53 54 /** 55 * Second step in the safety evaluation. Regex used to replace all simple 56 * values with ']' characters. 57 * 58 * @property _VALUES 59 * @type {RegExp} 60 * @static 61 * @private 62 */ 63 _VALUES = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, 64 65 /** 66 * Third step in the safety evaluation. Regex used to remove all open 67 * square brackets following a colon, comma, or at the beginning of the 68 * string. 69 * 70 * @property _BRACKETS 71 * @type {RegExp} 72 * @static 73 * @private 74 */ 75 _BRACKETS = /(?:^|:|,)(?:\s*\[)+/g, 76 77 /** 78 * Final step in the safety evaluation. Regex used to test the string left 79 * after all previous replacements for invalid characters. 80 * 81 * @property _UNSAFE 82 * @type {RegExp} 83 * @static 84 * @private 85 */ 86 _UNSAFE = /[^\],:{}\s]/, 87 88 89 /* Variables used by stringify */ 90 91 /** 92 * Regex used to replace special characters in strings for JSON 93 * stringification. 94 * 95 * @property _SPECIAL_CHARS 96 * @type {RegExp} 97 * @static 98 * @private 99 */ 100 _SPECIAL_CHARS = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 101 102 /** 103 * Character substitution map for common escapes and special characters. 104 * 105 * @property _CHARS 106 * @type {Object} 107 * @static 108 * @private 109 */ 110 _CHARS = { 111 '\b': '\\b', 112 '\t': '\\t', 113 '\n': '\\n', 114 '\f': '\\f', 115 '\r': '\\r', 116 '"' : '\\"', 117 '\\': '\\\\' 118 }, 119 120 UNDEFINED = 'undefined', 121 OBJECT = 'object', 122 NULL = 'null', 123 STRING = 'string', 124 NUMBER = 'number', 125 BOOLEAN = 'boolean', 126 DATE = 'date', 127 _allowable = { 128 'undefined' : UNDEFINED, 129 'string' : STRING, 130 '[object String]' : STRING, 131 'number' : NUMBER, 132 '[object Number]' : NUMBER, 133 'boolean' : BOOLEAN, 134 '[object Boolean]' : BOOLEAN, 135 '[object Date]' : DATE, 136 '[object RegExp]' : OBJECT 137 }, 138 EMPTY = '', 139 OPEN_O = '{', 140 CLOSE_O = '}', 141 OPEN_A = '[', 142 CLOSE_A = ']', 143 COMMA = ',', 144 COMMA_CR = ",\n", 145 CR = "\n", 146 COLON = ':', 147 COLON_SP = ': ', 148 QUOTE = '"'; 149 150 // Only accept JSON objects that report a [[Class]] of JSON 151 Native = _toStr.call(Native) === '[object JSON]' && Native; 152 153 // Escapes a special character to a safe Unicode representation 154 function _char(c) { 155 if (!_CHARS[c]) { 156 _CHARS[c] = '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4); 157 } 158 return _CHARS[c]; 159 } 160 161 162 /* functions used by parse */ 163 164 /** 165 * Traverses nested objects, applying a filter or reviver function to 166 * each value. The value returned from the function will replace the 167 * original value in the key:value pair. If the value returned is 168 * undefined, the key will be omitted from the returned object. 169 * 170 * @method _revive 171 * @param data {MIXED} Any JavaScript data 172 * @param reviver {Function} filter or mutation function 173 * @return {MIXED} The results of the filtered/mutated data structure 174 * @private 175 */ 176 function _revive(data, reviver) { 177 var walk = function (o,key) { 178 var k,v,value = o[key]; 179 if (value && typeof value === 'object') { 180 for (k in value) { 181 if (l.hasOwnProperty(value,k)) { 182 v = walk(value, k); 183 if (v === undefined) { 184 delete value[k]; 185 } else { 186 value[k] = v; 187 } 188 } 189 } 190 } 191 return reviver.call(o,key,value); 192 }; 193 194 return typeof reviver === 'function' ? walk({'':data},'') : data; 195 } 196 197 /** 198 * Replace certain Unicode characters that may be handled incorrectly by 199 * some browser implementations. 200 * 201 * @method _prepare 202 * @param s {String} parse input 203 * @return {String} sanitized JSON string ready to be validated/parsed 204 * @private 205 */ 206 function _prepare(s) { 207 return s.replace(_UNICODE_EXCEPTIONS, _char); 208 } 209 210 function _isSafe(str) { 211 return l.isString(str) && 212 !_UNSAFE.test(str.replace(_ESCAPES,'@'). 213 replace(_VALUES,']'). 214 replace(_BRACKETS,'')); 215 } 216 217 function _parse(s,reviver) { 218 // sanitize 219 s = _prepare(s); 220 221 // Ensure valid JSON 222 if (_isSafe(s)) { 223 // Eval the text into a JavaScript data structure, apply the 224 // reviver function if provided, and return 225 return _revive( eval('(' + s + ')'), reviver ); 226 } 227 228 // The text is not valid JSON 229 throw new SyntaxError('JSON.parse'); 230 } 231 232 233 234 /* functions used by stringify */ 235 236 // Utility function used to determine how to serialize a variable. 237 function _type(o) { 238 var t = typeof o; 239 return _allowable[t] || // number, string, boolean, undefined 240 _allowable[_toStr.call(o)] || // Number, String, Boolean, Date 241 (t === OBJECT ? 242 (o ? OBJECT : NULL) : // object, array, null, misc natives 243 UNDEFINED); // function, unknown 244 } 245 246 // Enclose escaped strings in quotes 247 function _string(s) { 248 return QUOTE + s.replace(_SPECIAL_CHARS, _char) + QUOTE; 249 } 250 251 // Adds the provided space to the beginning of every line in the input string 252 function _indent(s,space) { 253 return s.replace(/^/gm, space); 254 } 255 256 // JavaScript implementation of stringify (see API declaration of stringify) 257 function _stringify(o,w,space) { 258 if (o === undefined) { 259 return undefined; 260 } 261 262 var replacer = isFunction(w) ? w : null, 263 format = _toStr.call(space).match(/String|Number/) || [], 264 _date = YAHOO.lang.JSON.dateToString, 265 stack = [], 266 tmp,i,len; 267 268 if (replacer || !isArray(w)) { 269 w = undefined; 270 } 271 272 // Ensure whitelist keys are unique (bug 2110391) 273 if (w) { 274 tmp = {}; 275 for (i = 0, len = w.length; i < len; ++i) { 276 tmp[w[i]] = true; 277 } 278 w = tmp; 279 } 280 281 // Per the spec, strings are truncated to 10 characters and numbers 282 // are converted to that number of spaces (max 10) 283 space = format[0] === 'Number' ? 284 new Array(Math.min(Math.max(0,space),10)+1).join(" ") : 285 (space || EMPTY).slice(0,10); 286 287 function _serialize(h,key) { 288 var value = h[key], 289 t = _type(value), 290 a = [], 291 colon = space ? COLON_SP : COLON, 292 arr, i, keys, k, v; 293 294 // Per the ECMA 5 spec, toJSON is applied before the replacer is 295 // called. Also per the spec, Date.prototype.toJSON has been added, so 296 // Date instances should be serialized prior to exposure to the 297 // replacer. I disagree with this decision, but the spec is the spec. 298 if (isObject(value) && isFunction(value.toJSON)) { 299 value = value.toJSON(key); 300 } else if (t === DATE) { 301 value = _date(value); 302 } 303 304 if (isFunction(replacer)) { 305 value = replacer.call(h,key,value); 306 } 307 308 if (value !== h[key]) { 309 t = _type(value); 310 } 311 312 switch (t) { 313 case DATE : // intentional fallthrough. Pre-replacer Dates are 314 // serialized in the toJSON stage. Dates here would 315 // have been produced by the replacer. 316 case OBJECT : break; 317 case STRING : return _string(value); 318 case NUMBER : return isFinite(value) ? value+EMPTY : NULL; 319 case BOOLEAN : return value+EMPTY; 320 case NULL : return NULL; 321 default : return undefined; 322 } 323 324 // Check for cyclical references in nested objects 325 for (i = stack.length - 1; i >= 0; --i) { 326 if (stack[i] === value) { 327 throw new Error("JSON.stringify. Cyclical reference"); 328 } 329 } 330 331 arr = isArray(value); 332 333 // Add the object to the processing stack 334 stack.push(value); 335 336 if (arr) { // Array 337 for (i = value.length - 1; i >= 0; --i) { 338 a[i] = _serialize(value, i) || NULL; 339 } 340 } else { // Object 341 // If whitelist provided, take only those keys 342 keys = w || value; 343 i = 0; 344 345 for (k in keys) { 346 if (l.hasOwnProperty(keys, k)) { 347 v = _serialize(value, k); 348 if (v) { 349 a[i++] = _string(k) + colon + v; 350 } 351 } 352 } 353 } 354 355 // remove the array from the stack 356 stack.pop(); 357 358 if (space && a.length) { 359 return arr ? 360 OPEN_A + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_A : 361 OPEN_O + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_O; 362 } else { 363 return arr ? 364 OPEN_A + a.join(COMMA) + CLOSE_A : 365 OPEN_O + a.join(COMMA) + CLOSE_O; 366 } 367 } 368 369 // process the input 370 return _serialize({'':o},''); 371 } 372 373 374 /* Public API */ 375 YAHOO.lang.JSON = { 376 /** 377 * Leverage native JSON parse if the browser has a native implementation. 378 * In general, this is a good idea. See the Known Issues section in the 379 * JSON user guide for caveats. The default value is true for browsers with 380 * native JSON support. 381 * 382 * @property useNativeParse 383 * @type Boolean 384 * @default true 385 * @static 386 */ 387 useNativeParse : !!Native, 388 389 /** 390 * Leverage native JSON stringify if the browser has a native 391 * implementation. In general, this is a good idea. See the Known Issues 392 * section in the JSON user guide for caveats. The default value is true 393 * for browsers with native JSON support. 394 * 395 * @property useNativeStringify 396 * @type Boolean 397 * @default true 398 * @static 399 */ 400 useNativeStringify : !!Native, 401 402 /** 403 * Four step determination whether a string is safe to eval. In three steps, 404 * escape sequences, safe values, and properly placed open square brackets 405 * are replaced with placeholders or removed. Then in the final step, the 406 * result of all these replacements is checked for invalid characters. 407 * 408 * @method isSafe 409 * @param str {String} JSON string to be tested 410 * @return {boolean} is the string safe for eval? 411 * @static 412 */ 413 isSafe : function (s) { 414 return _isSafe(_prepare(s)); 415 }, 416 417 /** 418 * <p>Parse a JSON string, returning the native JavaScript 419 * representation.</p> 420 * 421 * <p>When lang.JSON.useNativeParse is true, this will defer to the native 422 * JSON.parse if the browser has a native implementation. Otherwise, a 423 * JavaScript implementation based on http://www.json.org/json2.js 424 * is used.</p> 425 * 426 * @method parse 427 * @param s {string} JSON string data 428 * @param reviver {function} (optional) function(k,v) passed each key:value 429 * pair of object literals, allowing pruning or altering values 430 * @return {MIXED} the native JavaScript representation of the JSON string 431 * @throws SyntaxError 432 * @static 433 */ 434 parse : function (s,reviver) { 435 if (typeof s !== 'string') { 436 s += ''; 437 } 438 439 return Native && YAHOO.lang.JSON.useNativeParse ? 440 Native.parse(s,reviver) : _parse(s,reviver); 441 }, 442 443 /** 444 * <p>Converts an arbitrary value to a JSON string representation.</p> 445 * 446 * <p>Objects with cyclical references will trigger an exception.</p> 447 * 448 * <p>If a whitelist is provided, only matching object keys will be 449 * included. Alternately, a replacer function may be passed as the 450 * second parameter. This function is executed on every value in the 451 * input, and its return value will be used in place of the original value. 452 * This is useful to serialize specialized objects or class instances.</p> 453 * 454 * <p>If a positive integer or non-empty string is passed as the third 455 * parameter, the output will be formatted with carriage returns and 456 * indentation for readability. If a String is passed (such as "\t") it 457 * will be used once for each indentation level. If a number is passed, 458 * that number of spaces will be used.</p> 459 * 460 * <p>When lang.JSON.useNativeStringify is true, this will defer to the 461 * native JSON.stringify if the browser has a native implementation. 462 * Otherwise, a JavaScript implementation is used.</p> 463 * 464 * @method stringify 465 * @param o {MIXED} any arbitrary object to convert to JSON string 466 * @param w {Array|Function} (optional) whitelist of acceptable object keys 467 * to include OR a function(value,key) to alter values 468 * before serialization 469 * @param space {Number|String} (optional) indentation character(s) or 470 * depthy of spaces to format the output 471 * @return {string} JSON string representation of the input 472 * @throws Error 473 * @static 474 */ 475 stringify : function (o,w,space) { 476 return Native && YAHOO.lang.JSON.useNativeStringify ? 477 Native.stringify(o,w,space) : _stringify(o,w,space); 478 }, 479 480 /** 481 * Serializes a Date instance as a UTC date string. Used internally by 482 * the JavaScript implementation of stringify. If you need a different 483 * Date serialization format, override this method. If you change this, 484 * you should also set useNativeStringify to false, since native JSON 485 * implementations serialize Dates per the ECMAScript 5 spec. You've been 486 * warned. 487 * 488 * @method dateToString 489 * @param d {Date} The Date to serialize 490 * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ 491 * @static 492 */ 493 dateToString : function (d) { 494 function _zeroPad(v) { 495 return v < 10 ? '0' + v : v; 496 } 497 498 return d.getUTCFullYear() + '-' + 499 _zeroPad(d.getUTCMonth() + 1) + '-' + 500 _zeroPad(d.getUTCDate()) + 'T' + 501 _zeroPad(d.getUTCHours()) + COLON + 502 _zeroPad(d.getUTCMinutes()) + COLON + 503 _zeroPad(d.getUTCSeconds()) + 'Z'; 504 }, 505 506 /** 507 * Reconstitute Date instances from the default JSON UTC serialization. 508 * Reference this from a reviver function to rebuild Dates during the 509 * parse operation. 510 * 511 * @method stringToDate 512 * @param str {String} String serialization of a Date 513 * @return {Date} 514 */ 515 stringToDate : function (str) { 516 var m = str.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{3}))?Z$/); 517 if (m) { 518 var d = new Date(); 519 d.setUTCFullYear(m[1], m[2]-1, m[3]); 520 d.setUTCHours(m[4], m[5], m[6], (m[7] || 0)); 521 return d; 522 } 523 return str; 524 } 525 }; 526 527 /** 528 * <p>Four step determination whether a string is safe to eval. In three steps, 529 * escape sequences, safe values, and properly placed open square brackets 530 * are replaced with placeholders or removed. Then in the final step, the 531 * result of all these replacements is checked for invalid characters.</p> 532 * 533 * <p>This is an alias for isSafe.</p> 534 * 535 * @method isValid 536 * @param str {String} JSON string to be tested 537 * @return {boolean} is the string safe for eval? 538 * @static 539 * @deprecated use isSafe 540 */ 541 YAHOO.lang.JSON.isValid = YAHOO.lang.JSON.isSafe; 542 543 })(); 544 YAHOO.register("json", YAHOO.lang.JSON, {version: "2.9.0", build: "2800"}); 545 546 }, '2.9.0' ,{"requires": ["yui2-yahoo"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |