diff --git a/doc/Tool_Api.md b/doc/Tool_Api.md index 0cbe3d1..0de19bf 100644 --- a/doc/Tool_Api.md +++ b/doc/Tool_Api.md @@ -4,7 +4,7 @@ Each default tool provided by eruda can be accessed by `eruda.get('Tool Name')`. ## Console -Displays console logs. Implementation detail follows the [console api spec](https://github.com/DeveloperToolsWG/console-object/blob/master/api.md). +Display console logs. Implementation detail follows the [console api spec](https://github.com/DeveloperToolsWG/console-object/blob/master/api.md). ### Config @@ -37,7 +37,7 @@ console.error(new Error('eruda')); ### filter -Filters logs. +Filter logs. |Name |Type |Desc | |------|----------------------|-------------| @@ -54,7 +54,7 @@ console.filter(function (log) ### html -Logs out html content. +Log out html content. |Name|Type |Desc | |----|------|-----------| diff --git a/src/Sources/Sources.scss b/src/Sources/Sources.scss index b55d5e8..d3b7100 100644 --- a/src/Sources/Sources.scss +++ b/src/Sources/Sources.scss @@ -32,6 +32,7 @@ } } .json { + background: #fff; padding: $padding 25px 10px; } .http { diff --git a/src/lib/JsonViewer.es6 b/src/lib/JsonViewer.es6 index f42c9fa..1878134 100644 --- a/src/lib/JsonViewer.es6 +++ b/src/lib/JsonViewer.es6 @@ -61,6 +61,7 @@ function createEl(key, val, firstLevel) close = '}'; if (key === 'erudaProto') key = '__proto__'; + if (key === 'erudaId') return `
  • `; if (util.isArr(val)) { @@ -103,6 +104,10 @@ function createEl(key, val, firstLevel) ${encode(val)} `; } + if (util.isStr(val) && util.startWith(val, 'erudaJson')) + { + return `
  • `; + } if (util.isStr(val) && util.startWith(val, 'function')) { return `
  • @@ -110,7 +115,7 @@ function createEl(key, val, firstLevel) ${encode(val).replace('function', 'function')}
  • `; } - if (val === '(...)' || val === '[circular]' || val === 'undefined' || val === 'Symbol') + if (val === '(...)' || val === 'undefined' || val === 'Symbol') { return `
  • ${wrapKey(key)} @@ -118,13 +123,18 @@ function createEl(key, val, firstLevel)
  • `; } + if (util.isStr(val) && util.startWith(val, '[circular]')) + { + let id = util.last(val.split(' ')); + return `
  • `; + } + return `
  • ${wrapKey(key)} "${encode(val)}"
  • `; } - const LIGHTER_KEY = ['__proto__', 'constructor', 'toString', 'valueOf', 'length']; var encode = str => util.escape(util.toStr(str)); \ No newline at end of file diff --git a/src/lib/stringify.es6 b/src/lib/stringify.es6 index bde4451..155dac5 100644 --- a/src/lib/stringify.es6 +++ b/src/lib/stringify.es6 @@ -21,6 +21,8 @@ export default function stringify(obj, { names = [], objEllipsis = '', proto, + circularId, + id = '', circular = false; topObj = topObj || obj; @@ -66,6 +68,15 @@ export default function stringify(obj, { wrapBool = bool => boolWrapper + bool + wrapperEnd, wrapNull = str => nullWrapper + str + wrapperEnd; + function visit(value) + { + let id = util.uniqId('erudaJson'); + + visited.push({id, value}); + + return id; + } + function wrapStr(str) { str = util.toStr(str); @@ -81,6 +92,10 @@ export default function stringify(obj, { { return specialWrapper + strEscape(str) + wrapperEnd; } + if (util.startWith(str, '[circular]')) + { + return specialWrapper + '[circular]' + wrapperEnd; + } if (util.startWith(str, '[object ')) { return specialWrapper + strEscape(str.replace(/(\[object )|]/g, '')) + wrapperEnd; @@ -106,27 +121,29 @@ export default function stringify(obj, { for (let i = 0, len = visited.length; i < len; i++) { - if (obj === visited[i]) + if (obj === visited[i].value) { circular = true; + circularId = visited[i].id; break; } } if (circular) { - json = wrapStr('[circular]'); + json = wrapStr('[circular]' + ' ' + circularId); } else if (isStr) { json = wrapStr(escapeJsonStr(obj)); } else if (isArr) { - visited.push(obj); + id = visit(obj); if (doStringify) { json = '['; util.each(obj, val => parts.push(`${stringify(val, passOpts)}`)); + if (!simple) parts.push(`"${id}"`); json += parts.join(', ') + ']'; } else { @@ -134,11 +151,12 @@ export default function stringify(obj, { } } else if (isObj || isFn) { - visited.push(obj); + id = visit(obj); + if (canBeProto(obj)) { obj = Object.getPrototypeOf(obj); - visited.push(obj); + id = visit(obj); } names = unenumerable ? Object.getOwnPropertyNames(obj) : Object.keys(obj); @@ -168,6 +186,7 @@ export default function stringify(obj, { if (fnStr.length > 500) fnStr = fnStr.slice(0, 500) + '...'; parts.push(`${wrapKey('erudaObjAbstract')}: ${wrapStr(escapeJsonStr(fnStr))}`); } + if (!simple) parts.push(`"erudaId": "${id}"`); util.each(names, name => { let key = wrapKey(escapeJsonStr(name)); @@ -225,17 +244,21 @@ export default function stringify(obj, { } else { try { - visited.push(obj); + id = visit(obj); if (canBeProto(obj)) { obj = Object.getPrototypeOf(obj); - visited.push(obj); + id = visit(obj); } if (doStringify) { json = '{ '; - if (!simple) parts.push(`${wrapKey('erudaObjAbstract')}: "${type.replace(/(\[object )|]/g, '')}"`); + if (!simple) + { + parts.push(`${wrapKey('erudaObjAbstract')}: "${type.replace(/(\[object )|]/g, '')}"`); + parts.push(`"erudaId": "${id}"`); + } names = unenumerable ? Object.getOwnPropertyNames(obj) : Object.keys(obj); if (keyNum && names.length > keyNum) objEllipsis = '...'; if (keyNum) names = names.slice(0, keyNum); @@ -274,7 +297,8 @@ export default function stringify(obj, { { json = wrapStr(obj); } - } catch (e) { + } catch (e) + { json = wrapStr(obj); } } @@ -282,7 +306,7 @@ export default function stringify(obj, { return json; } -const SPECIAL_VAL = ['(...)', '[circular]', 'undefined', 'Symbol', 'Object']; +const SPECIAL_VAL = ['(...)', 'undefined', 'Symbol', 'Object']; var escapeJsonStr = str => str.replace(/\\/g, '\\\\') .replace(/"/g, '\\"')