mirror of
https://github.com/liriliri/eruda.git
synced 2026-04-01 10:18:35 +08:00
Dev: Object display
This commit is contained in:
@@ -184,22 +184,6 @@ var getAbstract = util.wrap(origGetAbstract, function (fn, obj)
|
||||
});
|
||||
});
|
||||
|
||||
function stringifyWrapper(obj, options = {})
|
||||
{
|
||||
util.defaults(options, {
|
||||
simple: true,
|
||||
keyNum: 5,
|
||||
sortKeys: false,
|
||||
highlight: true,
|
||||
keyQuotes: false,
|
||||
specialVal: true,
|
||||
getterVal: Log.showGetterVal,
|
||||
unenumerable: false
|
||||
});
|
||||
|
||||
return stringify(obj, options);
|
||||
}
|
||||
|
||||
function formatTable(args)
|
||||
{
|
||||
let table = args[0],
|
||||
@@ -418,15 +402,9 @@ var render = data => tpl(data);
|
||||
function extractObj(obj, options = {})
|
||||
{
|
||||
util.defaults(options, {
|
||||
highlight: false,
|
||||
keyQuotes: true,
|
||||
simple: false,
|
||||
sortKeys: true,
|
||||
keyNum: 0,
|
||||
getterVal: Log.showGetterVal,
|
||||
unenumerable: Log.showUnenumerable,
|
||||
specialVal: false
|
||||
unenumerable: Log.showUnenumerable
|
||||
});
|
||||
|
||||
return JSON.parse(stringifyWrapper(obj, options));
|
||||
return JSON.parse(stringify(obj, options));
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import util from '../lib/util'
|
||||
import stringify from '../lib/stringify.es6'
|
||||
import highlight from '../lib/highlight.es6'
|
||||
import beautify from 'js-beautify'
|
||||
import Log from './Log.es6'
|
||||
|
||||
export default class Logger extends util.Emitter
|
||||
|
||||
@@ -103,11 +103,6 @@
|
||||
border-top: 1px solid $yellow;
|
||||
border-bottom: 1px solid $yellow;
|
||||
}
|
||||
&.dir, &.table, &.log, &.info, &.warn, &.output, &.debug {
|
||||
.json {
|
||||
padding-top: 10px;
|
||||
}
|
||||
}
|
||||
&.info {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
.json {
|
||||
background: #fff;
|
||||
padding: $padding 25px 10px;
|
||||
padding: 0 25px 10px;
|
||||
}
|
||||
.http {
|
||||
.breadcrumb {
|
||||
|
||||
@@ -23,6 +23,8 @@ export default class JsonViewer
|
||||
var $this = util.$(this),
|
||||
$firstSpan = util.$(this).find('span').eq(0);
|
||||
|
||||
if ($this.data('first-level') === 'true') return;
|
||||
|
||||
if (!$firstSpan.hasClass('eruda-expanded')) return;
|
||||
|
||||
e.stopImmediatePropagation();
|
||||
@@ -56,10 +58,16 @@ function jsonToHtml(data, firstLevel)
|
||||
|
||||
function createEl(key, val, firstLevel)
|
||||
{
|
||||
var type = 'object';
|
||||
let type = 'object',
|
||||
isUnenumerable = false;
|
||||
|
||||
if (key === 'erudaProto') key = '__proto__';
|
||||
if (key === 'erudaId') return `<li id="${val}" class="eruda-hidden"></li>`;
|
||||
if (util.startWith(key, 'erudaUnenumerable'))
|
||||
{
|
||||
key = util.trim(key.replace('erudaUnenumerable', ''));
|
||||
isUnenumerable = true;
|
||||
}
|
||||
|
||||
if (util.isArr(val)) type = 'array';
|
||||
|
||||
@@ -67,8 +75,8 @@ function createEl(key, val, firstLevel)
|
||||
{
|
||||
if (firstLevel) return '';
|
||||
|
||||
var keyClass = 'eruda-key';
|
||||
if (util.contain(LIGHTER_KEY, key)) keyClass = 'eruda-key-lighter';
|
||||
let keyClass = 'eruda-key';
|
||||
if (isUnenumerable || util.contain(LIGHTER_KEY, key)) keyClass = 'eruda-key-lighter';
|
||||
|
||||
return `<span class="${keyClass}">${encode(key)}</span>: `;
|
||||
}
|
||||
@@ -84,10 +92,10 @@ function createEl(key, val, firstLevel)
|
||||
{
|
||||
var objAbstract = val['erudaObjAbstract'] || util.upperFirst(type);
|
||||
|
||||
var obj = `<li>
|
||||
var obj = `<li data-first-level="${firstLevel}">
|
||||
<span class="eruda-expanded ${firstLevel ? '' : 'eruda-collapsed'}"></span>
|
||||
${wrapKey(key)}
|
||||
<span class="eruda-open">${objAbstract}</span>
|
||||
<span class="eruda-open">${firstLevel ? '' : objAbstract}</span>
|
||||
<ul class="eruda-${type}" ${firstLevel ? '' : 'style="display:none"'}>`;
|
||||
obj += jsonToHtml(val);
|
||||
|
||||
@@ -111,7 +119,7 @@ function createEl(key, val, firstLevel)
|
||||
<span class="eruda-function">${encode(val).replace('function', '')}</span>
|
||||
</li>`;
|
||||
}
|
||||
if (val === '(...)' || val === 'undefined' || val === 'Symbol')
|
||||
if (val === 'undefined' || val === 'Symbol')
|
||||
{
|
||||
return `<li>
|
||||
${wrapKey(key)}
|
||||
@@ -119,11 +127,11 @@ function createEl(key, val, firstLevel)
|
||||
</li>`;
|
||||
}
|
||||
|
||||
if (util.isStr(val) && util.startWith(val, '[circular]'))
|
||||
/*if (util.isStr(val) && util.startWith(val, '[circular]'))
|
||||
{
|
||||
let id = util.last(val.split(' '));
|
||||
return `<li class="eruda-circular" class="eruda-hidden" data-id="${id}"></li>`;
|
||||
}
|
||||
}*/
|
||||
|
||||
return `<li>
|
||||
${wrapKey(key)}
|
||||
@@ -131,6 +139,6 @@ function createEl(key, val, firstLevel)
|
||||
</li>`;
|
||||
}
|
||||
|
||||
const LIGHTER_KEY = ['__proto__', 'constructor', 'toString', 'valueOf', 'length'];
|
||||
const LIGHTER_KEY = ['__proto__'];
|
||||
|
||||
var encode = str => util.escape(util.toStr(str));
|
||||
@@ -74,8 +74,7 @@ export default function getAbstract(obj, {
|
||||
type = '[object Object]';
|
||||
}
|
||||
|
||||
var isFn = (type == '[object Function]'),
|
||||
isStr = (type == '[object String]'),
|
||||
let isStr = (type == '[object String]'),
|
||||
isArr = (type == '[object Array]'),
|
||||
isObj = (type == '[object Object]'),
|
||||
isNum = (type == '[object Number]'),
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
}
|
||||
ul {
|
||||
padding: 0 !important;
|
||||
padding-left: 20px !important;
|
||||
padding-left: 15px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
li {
|
||||
@@ -23,6 +23,9 @@
|
||||
& > li > .key {
|
||||
display: none;
|
||||
}
|
||||
& > li {
|
||||
padding: $padding 0;
|
||||
}
|
||||
.array .object .key {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -4,14 +4,9 @@ import util from './util'
|
||||
export default function stringify(obj, {
|
||||
visited = [],
|
||||
topObj,
|
||||
simple = false,
|
||||
level = 0,
|
||||
keyQuotes = true,
|
||||
getterVal = false,
|
||||
highlight = false,
|
||||
specialVal = false,
|
||||
sortKeys = true,
|
||||
keyNum = 0,
|
||||
unenumerable = true
|
||||
} = {})
|
||||
{
|
||||
@@ -19,54 +14,31 @@ export default function stringify(obj, {
|
||||
type = '',
|
||||
parts = [],
|
||||
names = [],
|
||||
objEllipsis = '',
|
||||
proto,
|
||||
circularId,
|
||||
allKeys, keys,
|
||||
id = '',
|
||||
circular = false;
|
||||
|
||||
topObj = topObj || obj;
|
||||
|
||||
let passOpts = {
|
||||
visited, specialVal, simple, getterVal, keyQuotes, highlight,
|
||||
unenumerable, keyNum, sortKeys,
|
||||
visited, specialVal, getterVal,
|
||||
unenumerable,
|
||||
level: level + 1
|
||||
},
|
||||
passProtoOpts = {
|
||||
visited, specialVal, getterVal, topObj, keyQuotes, highlight,
|
||||
unenumerable, keyNum, sortKeys,
|
||||
visited, specialVal, getterVal, topObj,
|
||||
unenumerable,
|
||||
level: level + 1
|
||||
};
|
||||
let dbQuotes = keyQuotes ? '"' : '',
|
||||
doStringify = !(simple && level > 0);
|
||||
|
||||
let keyWrapper = '',
|
||||
numWrapper = '',
|
||||
strWrapper = '',
|
||||
nullWrapper = '',
|
||||
boolWrapper = '',
|
||||
specialWrapper = '',
|
||||
let specialWrapper = '',
|
||||
fnWrapper = '',
|
||||
strEscape = str => str,
|
||||
wrapperEnd = '';
|
||||
|
||||
if (highlight)
|
||||
{
|
||||
keyWrapper = '<span style="color: #a71d5d;">';
|
||||
fnWrapper = '<span style="color: #a71d5d;">';
|
||||
numWrapper = '<span style="color: #0086b3;">';
|
||||
nullWrapper = '<span style="color: #0086b3;">';
|
||||
strWrapper = '<span style="color: #183691;">';
|
||||
boolWrapper = '<span style="color: #0086b3;">';
|
||||
specialWrapper = '<span style="color: #707d8b;">';
|
||||
strEscape = str => util.escape(str);
|
||||
wrapperEnd = '</span>';
|
||||
}
|
||||
|
||||
let wrapKey = key => keyWrapper + dbQuotes + strEscape(key) + dbQuotes + wrapperEnd,
|
||||
wrapNum = num => numWrapper + num + wrapperEnd,
|
||||
wrapBool = bool => boolWrapper + bool + wrapperEnd,
|
||||
wrapNull = str => nullWrapper + str + wrapperEnd;
|
||||
let wrapKey = key => '"' + strEscape(key) + '"';
|
||||
|
||||
function visit(value)
|
||||
{
|
||||
@@ -102,7 +74,7 @@ export default function stringify(obj, {
|
||||
}
|
||||
}
|
||||
|
||||
return strWrapper + strEscape(`"${str}"`) + wrapperEnd;
|
||||
return strEscape(`"${str}"`);
|
||||
}
|
||||
try {
|
||||
type = ({}).toString.call(obj);
|
||||
@@ -139,16 +111,10 @@ export default function stringify(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
|
||||
{
|
||||
json = wrapStr(`Array[${obj.length}]`);
|
||||
}
|
||||
json = '[';
|
||||
util.each(obj, val => parts.push(`${stringify(val, passOpts)}`));
|
||||
parts.push(`"${id}"`);
|
||||
json += parts.join(', ') + ']';
|
||||
} else if (isObj || isFn)
|
||||
{
|
||||
id = visit(obj);
|
||||
@@ -159,73 +125,56 @@ export default function stringify(obj, {
|
||||
id = visit(obj);
|
||||
}
|
||||
|
||||
names = unenumerable ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
|
||||
if (keyNum && names.length > keyNum) objEllipsis = '...';
|
||||
if (keyNum) names = names.slice(0, keyNum);
|
||||
allKeys = Object.getOwnPropertyNames(obj);
|
||||
keys = Object.keys(obj);
|
||||
names = unenumerable ? allKeys : keys;
|
||||
proto = Object.getPrototypeOf(obj);
|
||||
if (proto === Object.prototype || isFn || simple) proto = null;
|
||||
if (proto) proto = `${wrapKey('erudaProto')}: ${stringify(proto, passProtoOpts)}`;
|
||||
if (sortKeys) names.sort(sortObjName);
|
||||
names.sort(sortObjName);
|
||||
if (isFn)
|
||||
{
|
||||
// We don't need these properties to display for functions.
|
||||
names = names.filter(val => ['arguments', 'caller', 'name', 'length', 'prototype'].indexOf(val) < 0);
|
||||
names = names.filter(val => ['arguments', 'caller', 'prototype'].indexOf(val) < 0);
|
||||
}
|
||||
if (names.length === 0 && isFn)
|
||||
json = '{ ';
|
||||
if (isFn) parts.push(`${wrapKey('erudaObjAbstract')}: ${wrapStr(getFnAbstract(obj))}`);
|
||||
parts.push(`"erudaId": "${id}"`);
|
||||
util.each(names, name =>
|
||||
{
|
||||
json = wrapStr(escapeJsonStr(extractFnHead(obj)));
|
||||
} else
|
||||
{
|
||||
if (doStringify)
|
||||
{
|
||||
json = '{ ';
|
||||
if (isFn)
|
||||
{
|
||||
// Function length is restricted to 500 for performance reason.
|
||||
var fnStr = obj.toString();
|
||||
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));
|
||||
let unenumerable = !util.contain(keys, name) ? 'erudaUnenumerable' : '',
|
||||
key = wrapKey(unenumerable + ' ' + escapeJsonStr(name)),
|
||||
getKey = wrapKey(unenumerable + ' ' + escapeJsonStr('get ' + name)),
|
||||
setKey = wrapKey(unenumerable + ' ' + escapeJsonStr('set ' + name));
|
||||
|
||||
if (!getterVal)
|
||||
{
|
||||
let descriptor = Object.getOwnPropertyDescriptor(obj, name);
|
||||
if (descriptor.get)
|
||||
{
|
||||
parts.push(`${key}: ${wrapStr('(...)')}`);
|
||||
parts.push(`${wrapKey(escapeJsonStr('get ' + name))}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.get)))}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
parts.push(`${key}: ${stringify(topObj[name], passOpts)}`);
|
||||
});
|
||||
if (proto) parts.push(proto);
|
||||
json += parts.join(', ') + objEllipsis + ' }';
|
||||
} else
|
||||
let descriptor = Object.getOwnPropertyDescriptor(obj, name),
|
||||
hasGetter = descriptor && descriptor.get,
|
||||
hasSetter = descriptor && descriptor.set;
|
||||
if (!getterVal && hasGetter)
|
||||
{
|
||||
json = wrapStr('Object');
|
||||
parts.push(`${getKey}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.get)))}`);
|
||||
}
|
||||
}
|
||||
if (hasSetter)
|
||||
{
|
||||
parts.push(`${setKey}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.set)))}`);
|
||||
}
|
||||
if (!getterVal && hasGetter) return;
|
||||
parts.push(`${key}: ${stringify(topObj[name], passOpts)}`);
|
||||
});
|
||||
if (proto) parts.push(proto);
|
||||
json += parts.join(', ') + ' }';
|
||||
} else if (isNum)
|
||||
{
|
||||
json = obj + '';
|
||||
if (util.endWith(json, 'Infinity') || json === 'NaN')
|
||||
{
|
||||
json = `"${json}"`;
|
||||
} else
|
||||
{
|
||||
json = wrapNum(json);
|
||||
}
|
||||
} else if (isBool)
|
||||
{
|
||||
json = wrapBool(obj ? 'true' : 'false');
|
||||
json = obj ? 'true' : 'false';
|
||||
} else if (obj === null)
|
||||
{
|
||||
json = wrapNull('null');
|
||||
json = 'null';
|
||||
} else if (isSymbol)
|
||||
{
|
||||
json = wrapStr('Symbol');
|
||||
@@ -251,55 +200,51 @@ export default function stringify(obj, {
|
||||
id = visit(obj);
|
||||
}
|
||||
|
||||
if (doStringify)
|
||||
json = '{ ';
|
||||
parts.push(`${wrapKey('erudaObjAbstract')}: "${type.replace(/(\[object )|]/g, '')}"`);
|
||||
parts.push(`"erudaId": "${id}"`);
|
||||
allKeys = Object.getOwnPropertyNames(obj);
|
||||
keys = Object.keys(obj);
|
||||
names = unenumerable ? allKeys : keys;
|
||||
proto = Object.getPrototypeOf(obj);
|
||||
if (proto)
|
||||
{
|
||||
json = '{ ';
|
||||
if (!simple)
|
||||
try
|
||||
{
|
||||
parts.push(`${wrapKey('erudaObjAbstract')}: "${type.replace(/(\[object )|]/g, '')}"`);
|
||||
parts.push(`"erudaId": "${id}"`);
|
||||
proto = `${wrapKey('erudaProto')}: ${stringify(proto, passProtoOpts)}`;
|
||||
} catch(e)
|
||||
{
|
||||
proto = `${wrapKey('erudaProto')}: ${wrapStr(escapeJsonStr(e.message))}`;
|
||||
}
|
||||
names = unenumerable ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
|
||||
if (keyNum && names.length > keyNum) objEllipsis = '...';
|
||||
if (keyNum) names = names.slice(0, keyNum);
|
||||
proto = Object.getPrototypeOf(obj);
|
||||
if (proto === Object.prototype || simple) proto = null;
|
||||
if (proto)
|
||||
{
|
||||
try
|
||||
{
|
||||
proto = `${wrapKey('erudaProto')}: ${stringify(proto, passProtoOpts)}`;
|
||||
} catch(e)
|
||||
{
|
||||
proto = `${wrapKey('erudaProto')}: ${wrapStr(escapeJsonStr(e.message))}`;
|
||||
}
|
||||
}
|
||||
if (sortKeys) names.sort(sortObjName);
|
||||
util.each(names, name =>
|
||||
{
|
||||
let key = wrapKey(escapeJsonStr(name));
|
||||
|
||||
if (!getterVal)
|
||||
{
|
||||
let descriptor = Object.getOwnPropertyDescriptor(obj, name);
|
||||
if (descriptor.get)
|
||||
{
|
||||
parts.push(`${key}: ${wrapStr('(...)')}`);
|
||||
parts.push(`${wrapKey(escapeJsonStr('get ' + name))}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.get)))}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
parts.push(`${key}: ${stringify(topObj[name], passOpts)}`);
|
||||
});
|
||||
if (proto) parts.push(proto);
|
||||
json += parts.join(', ') + objEllipsis + ' }';
|
||||
} else
|
||||
{
|
||||
json = wrapStr(obj);
|
||||
}
|
||||
names.sort(sortObjName);
|
||||
util.each(names, name =>
|
||||
{
|
||||
let unenumerable = !util.contain(keys, name) ? 'erudaUnenumerable' : '',
|
||||
key = wrapKey(unenumerable + ' ' + escapeJsonStr(name)),
|
||||
getKey = wrapKey(unenumerable + ' ' + escapeJsonStr('get ' + name)),
|
||||
setKey = wrapKey(unenumerable + ' ' + escapeJsonStr('set ' + name));
|
||||
|
||||
let descriptor = Object.getOwnPropertyDescriptor(obj, name),
|
||||
hasGetter = descriptor && descriptor.get,
|
||||
hasSetter = descriptor && descriptor.set;
|
||||
if (!getterVal && hasGetter)
|
||||
{
|
||||
parts.push(`${getKey}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.get)))}`);
|
||||
}
|
||||
if (hasSetter)
|
||||
{
|
||||
parts.push(`${setKey}: ${wrapStr(escapeJsonStr(extractFnHead(descriptor.set)))}`);
|
||||
}
|
||||
if (!getterVal && hasGetter) return;
|
||||
parts.push(`${key}: ${stringify(topObj[name], passOpts)}`);
|
||||
});
|
||||
if (proto) parts.push(proto);
|
||||
json += parts.join(', ') + ' }';
|
||||
} catch (e)
|
||||
{
|
||||
json = wrapStr(obj);
|
||||
json = wrapStr(e.message);
|
||||
// json = wrapStr(obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,7 +290,7 @@ function cmpCode(a, b)
|
||||
|
||||
function transCode(code)
|
||||
{
|
||||
if (code === 95) return 123;
|
||||
if (code === 95) return 91;
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -361,6 +306,14 @@ function extractFnHead(fn)
|
||||
return str;
|
||||
}
|
||||
|
||||
function getFnAbstract(fn)
|
||||
{
|
||||
let fnStr = fn.toString();
|
||||
if (fnStr.length > 500) fnStr = fnStr.slice(0, 500) + '...';
|
||||
|
||||
return escapeJsonStr(extractFnHead(fnStr).replace('function', ''));
|
||||
}
|
||||
|
||||
function canBeProto(obj)
|
||||
{
|
||||
let emptyObj = util.isEmpty(Object.getOwnPropertyNames(obj)),
|
||||
|
||||
Reference in New Issue
Block a user