Add: Json viewer

This commit is contained in:
surunzi
2016-05-11 22:46:29 +08:00
parent b9bb951691
commit d48778ed57
11 changed files with 286 additions and 18 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "eruda",
"version": "0.3.0",
"version": "0.3.1",
"description": "Console for mobile JavaScript",
"main": "dist/eruda.js",
"scripts": {

View File

@@ -12,10 +12,11 @@ export default class Console extends Tool
super();
this.name = 'console';
}
init($el)
init($el, parent)
{
super.init($el);
this._parent = parent;
this._appendTpl();
this._initLog();
this._bindEvent();
@@ -116,6 +117,7 @@ export default class Console extends Tool
var $input = this._$input,
$inputBtns = this._$inputBtns,
$control = this._$control,
parent = this._parent,
log = this._log;
$control.on('click', '.clear-console', () => log.clear());
@@ -139,6 +141,12 @@ export default class Console extends Tool
});
$input.on('focusin', () => this._showInput());
log.on('viewJson', (data) =>
{
parent.get('sources').set('json', data);
parent.showTool('sources');
});
}
_hideInput()
{

View File

@@ -13,11 +13,14 @@ export default class Log extends util.Emitter
this._$el = $el;
this._parent = parent;
this._logs = [];
this._renderLogs = [];
this._tpl = require('./Log.hbs');
this._filter = 'all';
this._isUpdated = false;
this._lastLog = {};
this._timer = {};
this._bindEvent();
}
clear()
{
@@ -29,6 +32,8 @@ export default class Log extends util.Emitter
}
input(jsCode)
{
var src = jsCode;
jsCode = util.trim(jsCode);
if (util.startWith(jsCode, ':'))
@@ -47,6 +52,7 @@ export default class Log extends util.Emitter
type: 'input',
ignoreFilter: true,
isCode: true,
src: src,
val: jsCode
});
@@ -62,23 +68,23 @@ export default class Log extends util.Emitter
}
output(msg)
{
msg = transMsg(msg);
this._insert({
type: 'output',
ignoreFilter: true,
val: msg
src: msg,
val: transMsg(msg)
});
return this;
}
dir(obj)
{
var msg = util.isObj(obj) ? JSON.stringify(obj, null, 4) : transMsg(obj);
var msg = util.isObj(obj) ? JSON.stringify(obj, null, 4) : transMsg(obj, true);
this._insert({
type: 'dir',
isCode: true,
src: obj,
val: msg
});
@@ -86,10 +92,12 @@ export default class Log extends util.Emitter
}
log()
{
var msg = transMultipleMsg(arguments);
var msg = transMultipleMsg(arguments),
src = arguments.length === 1 ? arguments[0] : arguments;
this._insert({
type: 'log',
src,
val: msg
});
@@ -107,7 +115,8 @@ export default class Log extends util.Emitter
}
error(msg)
{
var ignoreFilter = false;
var src = msg,
ignoreFilter = false;
if (util.isErr(msg))
{
@@ -121,6 +130,7 @@ export default class Log extends util.Emitter
this._insert({
type: 'error',
ignoreFilter: ignoreFilter,
src: src,
val: msg
});
@@ -128,10 +138,12 @@ export default class Log extends util.Emitter
}
info()
{
var msg = transMultipleMsg(arguments);
var msg = transMultipleMsg(arguments),
src = arguments.length === 1 ? arguments[0] : arguments;
this._insert({
type: 'info',
src,
val: msg
});
@@ -139,10 +151,12 @@ export default class Log extends util.Emitter
}
warn()
{
var msg = transMultipleMsg(arguments);
var msg = transMultipleMsg(arguments),
src = arguments.length === 1 ? arguments[0] : arguments;
this._insert({
type: 'warn',
src,
val: msg
});
@@ -190,6 +204,8 @@ export default class Log extends util.Emitter
times: 1
});
log.src = log.src || log.val;
if (log.isCode)
{
log.val = highlight(beautify(log.val), 'js');
@@ -216,6 +232,22 @@ export default class Log extends util.Emitter
this._isUpdated = true;
this.render();
}
_bindEvent()
{
var self = this;
this._$el.on('click', '.eruda-log-item', function ()
{
var idx = util.$(this).data('idx');
var src = self._renderLogs[idx].src;
try {
if (!util.isObj(src)) src = JSON.parse(src);
self.emit('viewJson', src);
} catch (e) {}
});
}
_runCmd(cmd)
{
cmd = util.trim(cmd);
@@ -250,7 +282,7 @@ export default class Log extends util.Emitter
this._isUpdated = false;
var logs = this._filterLogs(this._logs);
var logs = this._renderLogs = this._filterLogs(this._logs);
this._$el.html(this._tpl({
logs: logs
@@ -310,7 +342,7 @@ function errToStr(err, msg)
return msg + stack;
}
function transMsg(msg)
function transMsg(msg, noEscape)
{
if (util.isUndef(msg))
{
@@ -326,7 +358,11 @@ function transMsg(msg)
msg = 'Object ' + JSON.stringify(msg);
}
return util.escape(util.toStr(msg));
msg = util.toStr(msg);
if (noEscape) return msg;
return util.escape(msg);
}
function transMultipleMsg(args)

View File

@@ -1,6 +1,6 @@
<ul>
{{#each logs}}
<li class="eruda-{{type}}">
<li class="eruda-{{type}} eruda-log-item" data-idx="{{@index}}">
{{#if showTimes}}<span class="eruda-times">{{times}}</span>{{/if}}
{{#if isCode}}
<pre>{{{val}}}</pre>

View File

@@ -0,0 +1,90 @@
import util from '../lib/util'
export default class JsonViewer
{
constructor(data, $el)
{
this._data = [data];
this._$el = $el;
this._appendTpl();
this._bindEvent();
}
_appendTpl()
{
this._$el.html(jsonToHtml(this._data));
}
_bindEvent()
{
this._$el.on('click', '.eruda-expanded', function ()
{
var $this = util.$(this);
$this.parent().find('ul').eq(0).hide();
$this.addClass('eruda-collapsed');
}).on('click', '.eruda-expanded.eruda-collapsed', function ()
{
var $this = util.$(this);
$this.rmClass('eruda-collapsed');
$this.parent().find('ul').eq(0).show();
});
}
}
function jsonToHtml(data)
{
var ret = '';
util.each(data, (val, key) => ret += createEl(key, val));
return ret;
}
function createEl(key, val)
{
var type = 'object',
open = '{',
close = '}';
if (util.isArr(val))
{
type = 'array';
open = '[';
close = ']';
}
if (val === null)
{
return '<li>' +
'<span class="eruda-key">"' + encode(key) + '": </span>' +
'<span class="eruda-null">"' + encode(val) + '"</span>' +
'</li>';
}
if (util.isObj(val))
{
var obj = '<li>' + '<span class="eruda-expanded"></span>' +
'<span class="eruda-key">"' + encode(key) + '": </span>' +
'<span class="eruda-open">' + open + '</span>' +
'<ul class="eruda-' + type + '">';
obj += jsonToHtml(val);
return obj + '</ul><span class="eruda-close">' + close + '</span></li>';
}
if (util.isNum(val) || util.isBool(val))
{
return '<li>' +
'<span class="eruda-key">"' + encode(key) + '": </span>' +
'<span class="eruda-'+ typeof val + '">' + encode(val) + '</span>' +
'</li>';
}
return '<li>' +
'<span class="eruda-key">"' + encode(key) + '": </span>' +
'<span class="eruda-'+ typeof val + '">"' + encode(val) + '"</span>' +
'</li>';
}
function encode(str)
{
return util.escape(util.toStr(str));
}

View File

@@ -2,6 +2,7 @@ import Tool from '../DevTools/Tool.es6'
import util from '../lib/util'
import beautify from 'js-beautify'
import highlight from '../lib/highlight.es6'
import JsonViewer from './JsonViewer.es6'
require('./Sources.scss');
@@ -105,6 +106,7 @@ export default class Sources extends Tool
case 'css': return this.set('css', resTxt);
case 'html': return this.set('html', resTxt);
case 'javascript': return this.set('js', resTxt);
case 'json': return this.set('json', resTxt);
}
switch (data.type)
{
@@ -117,6 +119,7 @@ export default class Sources extends Tool
this._codeTpl = require('./code.hbs');
this._imgTpl = require('./image.hbs');
this._httpTpl = require('./http.hbs');
this._jsonTpl = require('./json.hbs');
}
_render()
{
@@ -134,6 +137,8 @@ export default class Sources extends Tool
return this._renderImg();
case 'http':
return this._renderHttp();
case 'json':
return this._renderJson();
}
}
_renderImg()
@@ -171,4 +176,15 @@ export default class Sources extends Tool
this._$el.html(this._codeTpl({code: code}));
}
_renderJson()
{
this._$el.html(this._jsonTpl());
var val = this._data.val;
try {
if (util.isStr(val)) val = JSON.parse(val);
new JsonViewer(val, this._$el.find('.eruda-json'));
} catch (e) {}
}
}

View File

@@ -56,5 +56,80 @@
-webkit-overflow-scrolling: touch;
}
}
.json {
font-size: 14px;
line-height: 1.2;
background: #fff;
min-height: 100%;
padding: $common-padding 25px 10px;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
&, ul {
list-style: none !important;
}
ul {
padding: 0 !important;
padding-left: 20px !important;
margin: 0 !important;
}
li {
position: relative;
}
& > li > .key,
& .array .key {
display: none;
}
.array .object .key {
display: inline;
}
li:after {
content: ",";
}
li:last-child:after {
content: "";
}
.null {
color: #a71d5d;
}
.string {
color: #183691;
}
.number {
color: #0086b3;
}
.boolean {
color: #a71d5d;
}
.key {
color: #183691;
}
.expanded:before {
content: "-";
font-size: 1.5em;
width: 13px;
text-align: center;
line-height: 13px;
font-family: sans-serif;
position: absolute;
left: -15px;
top: 0;
}
.collapsed:before {
content: "+";
font-size: 1.5em;
color: #000;
top: 1px;
}
li .collapsed ~ .close:before {
content: "... ";
color: #999;
}
.hidden ~ ul {
display: none;
}
span {
position: static !important;
}
}
}
} }

1
src/Sources/json.hbs Normal file
View File

@@ -0,0 +1 @@
<ul class="eruda-json"></ul>

View File

@@ -55,7 +55,7 @@ export default function highlight(str, lang)
util.each(lang, (val, key) =>
{
str = str.replace(new RegExp("___end"+ key +"___","g"), "</span>")
.replace(new RegExp("___"+ key +"___","g"), "<span class='litelighterstyle' style='"+ style[val.style] +"'>");
.replace(new RegExp("___"+ key +"___","g"), "<span style='"+ style[val.style] +"'>");
});
util.each(lang, (val) =>

View File

@@ -909,6 +909,32 @@ module.exports = (function ()
return exports;
})({});
/* ------------------------------ isBool ------------------------------ */
var isBool = _.isBool = (function (exports)
{
/* Check if value is a boolean primitive.
*
* |Name |Type |Desc |
* |-----------------------------------------|
* |val |* |The value to check |
* |return|boolean|True if value is a boolean|
*
* ```javascript
* isBool(true); // -> true
* isBool(false); // -> true
* isBool(1); // -> false
* ```
*/
exports = function (val)
{
return val === true || val === false;
};
return exports;
})({});
/* ------------------------------ isEl ------------------------------ */
var isEl = _.isEl = (function (exports)

View File

@@ -1,3 +1,19 @@
{
"name": "eruda"
}
[
{
"name": "Test",
"author": {
"name": "Redhoodsu",
"email": "surunzi@foxmail.com",
"contact": [
{
"location": "<span>office</span>",
"number": 123456
},
{
"location": "A very very long long address!!!!!!!!!!!!",
"number": 654321
}
]
}
}
]