123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- var CircularJSON = (function(JSON, RegExp){
- var
-
-
-
-
- specialChar = '~',
- safeSpecialChar = '\\x' + (
- '0' + specialChar.charCodeAt(0).toString(16)
- ).slice(-2),
- escapedSafeSpecialChar = '\\' + safeSpecialChar,
- specialCharRG = new RegExp(safeSpecialChar, 'g'),
- safeSpecialCharRG = new RegExp(escapedSafeSpecialChar, 'g'),
- safeStartWithSpecialCharRG = new RegExp('(?:^|([^\\\\]))' + escapedSafeSpecialChar),
- indexOf = [].indexOf || function(v){
- for(var i=this.length;i--&&this[i]!==v;);
- return i;
- },
- $String = String
-
-
- ;
- function generateReplacer(value, replacer, resolve) {
- var
- doNotIgnore = false,
- inspect = !!replacer,
- path = [],
- all = [value],
- seen = [value],
- mapp = [resolve ? specialChar : '[Circular]'],
- last = value,
- lvl = 1,
- i, fn
- ;
- if (inspect) {
- fn = typeof replacer === 'object' ?
- function (key, value) {
- return key !== '' && replacer.indexOf(key) < 0 ? void 0 : value;
- } :
- replacer;
- }
- return function(key, value) {
-
-
-
-
- if (inspect) value = fn.call(this, key, value);
-
- if (doNotIgnore) {
- if (last !== this) {
- i = lvl - indexOf.call(all, this) - 1;
- lvl -= i;
- all.splice(lvl, all.length);
- path.splice(lvl - 1, path.length);
- last = this;
- }
-
- if (typeof value === 'object' && value) {
-
-
- if (indexOf.call(all, value) < 0) {
- all.push(last = value);
- }
- lvl = all.length;
- i = indexOf.call(seen, value);
- if (i < 0) {
- i = seen.push(value) - 1;
- if (resolve) {
-
- path.push(('' + key).replace(specialCharRG, safeSpecialChar));
- mapp[i] = specialChar + path.join(specialChar);
- } else {
- mapp[i] = mapp[0];
- }
- } else {
- value = mapp[i];
- }
- } else {
- if (typeof value === 'string' && resolve) {
-
-
-
- value = value .replace(safeSpecialChar, escapedSafeSpecialChar)
- .replace(specialChar, safeSpecialChar);
- }
- }
- } else {
- doNotIgnore = true;
- }
- return value;
- };
- }
- function retrieveFromPath(current, keys) {
- for(var i = 0, length = keys.length; i < length; current = current[
-
- keys[i++].replace(safeSpecialCharRG, specialChar)
- ]);
- return current;
- }
- function generateReviver(reviver) {
- return function(key, value) {
- var isString = typeof value === 'string';
- if (isString && value.charAt(0) === specialChar) {
- return new $String(value.slice(1));
- }
- if (key === '') value = regenerate(value, value, {});
-
-
- if (isString) value = value .replace(safeStartWithSpecialCharRG, '$1' + specialChar)
- .replace(escapedSafeSpecialChar, safeSpecialChar);
- return reviver ? reviver.call(this, key, value) : value;
- };
- }
- function regenerateArray(root, current, retrieve) {
- for (var i = 0, length = current.length; i < length; i++) {
- current[i] = regenerate(root, current[i], retrieve);
- }
- return current;
- }
- function regenerateObject(root, current, retrieve) {
- for (var key in current) {
- if (current.hasOwnProperty(key)) {
- current[key] = regenerate(root, current[key], retrieve);
- }
- }
- return current;
- }
- function regenerate(root, current, retrieve) {
- return current instanceof Array ?
-
- regenerateArray(root, current, retrieve) :
- (
- current instanceof $String ?
- (
-
- current.length ?
- (
- retrieve.hasOwnProperty(current) ?
- retrieve[current] :
- retrieve[current] = retrieveFromPath(
- root, current.split(specialChar)
- )
- ) :
- root
- ) :
- (
- current instanceof Object ?
-
- regenerateObject(root, current, retrieve) :
-
- current
- )
- )
- ;
- }
- var CircularJSON = {
- stringify: function stringify(value, replacer, space, doNotResolve) {
- return CircularJSON.parser.stringify(
- value,
- generateReplacer(value, replacer, !doNotResolve),
- space
- );
- },
- parse: function parse(text, reviver) {
- return CircularJSON.parser.parse(
- text,
- generateReviver(reviver)
- );
- },
-
-
-
- parser: JSON
- };
- return CircularJSON;
- }(JSON, RegExp));
|