chore: object viewer

This commit is contained in:
surunzi
2020-01-02 18:25:21 +08:00
parent e9ec1f3983
commit c466cd575c
9 changed files with 68 additions and 41 deletions

View File

@@ -555,10 +555,10 @@ function formatEl(val) {
)}</pre>`
}
const regUrl = /(^|[\s\n]|<[A-Za-z]*\/?>)((?:https?|ftp):\/\/[-A-Z0-9+\u0026\u2019@#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026@#/%=~()_|])/gi
const regUrl = /((?:https?|ftp):\/\/[-A-Z0-9+\u0026\u2019@#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026@#/%=~()_|])/gi
const recognizeUrl = str =>
str.replace(regUrl, '<a href="$2" target="_blank">$2</a>')
str.replace(regUrl, '<a href="$1" target="_blank">$1</a>')
function getFrom() {
const e = new Error()

View File

@@ -21,7 +21,6 @@ import {
pxToNum,
isNaN,
isNum,
stringifyAll,
nextTick,
Emitter
} from '../lib/util'
@@ -180,23 +179,10 @@ export default class Elements extends Tool {
}
})
.on('click', '.eruda-breadcrumb', () => {
let data = this._elData
if (!data) {
data = stringifyAll(this._curEl, {
unenumerable: true,
symbol: true,
accessGetter: true,
timeout: 1000
})
data = JSON.parse(data)
}
const sources = container.get('sources')
this._elData = data
if (sources) {
sources.set('json', data)
sources.set('object', this._curEl)
container.showTool('sources')
}
})
@@ -262,7 +248,6 @@ export default class Elements extends Tool {
}
_setEl(el) {
this._curEl = el
this._elData = null
this._curCssStore = new CssStore(el)
this._highlight.setEl(el)
this._rmDefComputedStyle = true

View File

@@ -187,7 +187,7 @@ export default class Network extends Tool {
case 'javascript':
return showSources('js', resTxt)
case 'json':
return showSources('json', resTxt)
return showSources('object', resTxt)
}
switch (data.type) {
case 'image':

View File

@@ -279,7 +279,7 @@ export default class Resources extends Tool {
: sessionStorage.getItem(key)
try {
showSources('json', JSON.parse(val))
showSources('object', JSON.parse(val))
} catch (e) {
showSources('raw', val)
}

View File

@@ -1,6 +1,6 @@
import Tool from '../DevTools/Tool'
import beautify from 'js-beautify'
import JsonViewer from '../lib/JsonViewer'
import ObjViewer from '../lib/ObjViewer'
import Settings from '../Settings/Settings'
import { ajax, escape, trim, isStr, highlight } from '../lib/util'
import evalCss from '../lib/evalCss'
@@ -109,7 +109,7 @@ export default class Sources extends Tool {
_loadTpl() {
this._codeTpl = require('./code.hbs')
this._imgTpl = require('./image.hbs')
this._jsonTpl = require('./json.hbs')
this._objTpl = require('./object.hbs')
this._rawTpl = require('./raw.hbs')
this._iframeTpl = require('./iframe.hbs')
}
@@ -164,8 +164,8 @@ export default class Sources extends Tool {
return this._renderCode()
case 'img':
return this._renderImg()
case 'json':
return this._renderJson()
case 'object':
return this._renderObj()
case 'raw':
return this._renderRaw()
case 'iframe':
@@ -225,9 +225,9 @@ export default class Sources extends Tool {
})
)
}
_renderJson() {
// Using cache will keep binding json events to the same elements.
this._renderHtml(this._jsonTpl(), false)
_renderObj() {
// Using cache will keep binding events to the same elements.
this._renderHtml(this._objTpl(), false)
let val = this._data.val
@@ -238,7 +238,10 @@ export default class Sources extends Tool {
/* eslint-disable no-empty */
} catch (e) {}
new JsonViewer(val, this._$el.find('.eruda-json'))
new ObjViewer(val, this._$el.find('.eruda-json'), {
showUnenumerable: true,
showGetterVal: true
})
}
_renderRaw() {
this._renderHtml(this._rawTpl({ val: this._data.val }))

View File

@@ -5,8 +5,8 @@ import {
uniqId,
upperFirst,
toNum,
escape,
toStr,
escape,
chunk,
each,
isNaN,
@@ -275,6 +275,8 @@ export const encode = str => {
// $, upperCase, lowerCase, _
export function sortObjName(a, b) {
a = toStr(a)
b = toStr(b)
const numA = toNum(a)
const numB = toNum(b)
if (!isNaN(numA) && !isNaN(numB)) {

View File

@@ -1,4 +1,5 @@
import {
extend,
Emitter,
getProto,
isNum,
@@ -45,6 +46,12 @@ export default class ObjViewer extends Emitter {
this._bindEvent()
}
_objToHtml(data, firstLevel) {
let self = data
const visitedObj = this._visitor.get(data)
if (visitedObj && visitedObj.self) {
self = visitedObj.self
}
let ret = ''
const types = ['enumerable']
@@ -86,15 +93,40 @@ export default class ObjViewer extends Emitter {
for (let i = 0, len = typeKeys.length; i < len; i++) {
const key = typeKeys[i]
let val = ''
try {
val = data[key]
if (isPromise(val)) {
val.catch(() => {})
const descriptor = Object.getOwnPropertyDescriptor(data, key)
const hasGetter = descriptor && descriptor.get
const hasSetter = descriptor && descriptor.set
if (hasGetter && !this._showGetterVal) {
val = '(...)'
} else {
try {
val = self[key]
if (isPromise(val)) {
val.catch(() => {})
}
} catch (e) {
val = e.message
}
} catch (e) {
val = e.message
}
ret += this._createEl(key, val, type, firstLevel)
ret += this._createEl(key, data, val, type, firstLevel)
if (hasGetter) {
ret += this._createEl(
`get ${key}`,
data,
descriptor.get,
type,
firstLevel
)
}
if (hasSetter) {
ret += this._createEl(
`set ${key}`,
data,
descriptor.set,
type,
firstLevel
)
}
}
})
@@ -103,13 +135,13 @@ export default class ObjViewer extends Emitter {
if (ret === '') {
ret = this._objToHtml(proto)
} else {
ret += this._createEl('__proto__', proto, 'proto')
ret += this._createEl('__proto__', self || data, proto, 'proto')
}
}
return ret
}
_createEl(key, val, keyType, firstLevel = false) {
_createEl(key, self, val, keyType, firstLevel = false) {
const visitor = this._visitor
let t = typeof val
const valType = type(val, false)
@@ -141,7 +173,11 @@ export default class ObjViewer extends Emitter {
if (visitedObj) {
id = visitedObj.id
} else {
id = visitor.set(val)
const extra = {}
if (keyType === 'proto') {
extra.self = self
}
id = visitor.set(val, extra)
this._map[id] = val
}
const objAbstract = getObjAbstract(val, valType) || upperFirst(t)
@@ -242,12 +278,13 @@ class Visitor {
this.id = 0
this.visited = []
}
set(val) {
set(val, extra) {
const { visited, id } = this
const obj = {
id,
val
}
extend(obj, extra)
visited.push(obj)
this.id++