mirror of
https://github.com/liriliri/eruda.git
synced 2026-03-20 09:38:37 +08:00
Dev: Console refactoring
This commit is contained in:
19
doc/Tool_Api.md
Normal file
19
doc/Tool_Api.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Tool Api
|
||||
|
||||
## Console
|
||||
|
||||
## Elements
|
||||
|
||||
## Network
|
||||
|
||||
## Resources
|
||||
|
||||
## Sources
|
||||
|
||||
## Info
|
||||
|
||||
## Snippets
|
||||
|
||||
## Features
|
||||
|
||||
## Settings
|
||||
@@ -1,4 +1,4 @@
|
||||
import Log from './Logger.es6'
|
||||
import Logger from './Logger.es6'
|
||||
import Tool from '../DevTools/Tool.es6'
|
||||
import util from '../lib/util'
|
||||
import config from '../lib/config.es6'
|
||||
@@ -17,7 +17,7 @@ export default class Console extends Tool
|
||||
|
||||
this._appendTpl();
|
||||
this._initLogger();
|
||||
this._exposeLog();
|
||||
this._exposeLogger();
|
||||
this._initConfig(parent);
|
||||
this._bindEvent(parent);
|
||||
}
|
||||
@@ -104,10 +104,10 @@ export default class Console extends Tool
|
||||
$this[isMatch ? 'addClass' : 'rmClass']('eruda-active');
|
||||
}));
|
||||
}
|
||||
_exposeLog()
|
||||
_exposeLogger()
|
||||
{
|
||||
let logger = this._logger,
|
||||
methods = ['filter'].concat(CONSOLE_METHOD);
|
||||
methods = ['filter', 'html'].concat(CONSOLE_METHOD);
|
||||
|
||||
methods.forEach(name => this[name] = (...args) =>
|
||||
{
|
||||
@@ -196,7 +196,7 @@ export default class Console extends Tool
|
||||
if (cfg.get('catchGlobalErr')) this.catchGlobalErr();
|
||||
if (cfg.get('overrideConsole')) this.overrideConsole();
|
||||
if (cfg.get('displayExtraInfo')) logger.displayExtraInfo(true);
|
||||
logger.setMaxNum(maxLogNum);
|
||||
logger.maxNum(maxLogNum);
|
||||
|
||||
cfg.on('change', (key, val) =>
|
||||
{
|
||||
@@ -204,7 +204,7 @@ export default class Console extends Tool
|
||||
{
|
||||
case 'catchGlobalErr': return val ? this.catchGlobalErr() : this.ignoreGlobalErr();
|
||||
case 'overrideConsole': return val ? this.overrideConsole() : this.restoreConsole();
|
||||
case 'maxLogNum': return logger.setMaxNum(val === 'infinite' ? val : +val);
|
||||
case 'maxLogNum': return logger.maxNum(val === 'infinite' ? val : +val);
|
||||
case 'displayExtraInfo': return logger.displayExtraInfo(val);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<span class="eruda-filter filter" data-filter="log">Log</span>
|
||||
<span class="eruda-icon-info-circle help" ontouchstart></span>
|
||||
</div>
|
||||
<div class="eruda-logs"></div>
|
||||
<ul class="eruda-logs"></ul>
|
||||
<div class="eruda-js-input">
|
||||
<div class="eruda-buttons">
|
||||
<div class="eruda-button cancel" ontouchstart>Cancel</div>
|
||||
|
||||
@@ -1,11 +1,242 @@
|
||||
import util from '../lib/util'
|
||||
import stringify from '../lib/stringify.es6'
|
||||
import highlight from '../lib/highlight.es6'
|
||||
import beautify from 'js-beautify'
|
||||
|
||||
export default class Log
|
||||
{
|
||||
constructor(type, args)
|
||||
constructor({type, args, idx, header})
|
||||
{
|
||||
this._type = type;
|
||||
this._args = args;
|
||||
this._timestamp = util.now();
|
||||
this._idx = idx;
|
||||
this._header = header;
|
||||
this._ignoreFilter = false;
|
||||
|
||||
this._preProcess();
|
||||
}
|
||||
get formattedMsg()
|
||||
{
|
||||
if (!this._formattedMsg) this._formatMsg();
|
||||
|
||||
return this._formattedMsg;
|
||||
}
|
||||
get ignoreFilter()
|
||||
{
|
||||
return this._ignoreFilter;
|
||||
}
|
||||
get type()
|
||||
{
|
||||
return this._type;
|
||||
}
|
||||
_preProcess()
|
||||
{
|
||||
switch (this._type)
|
||||
{
|
||||
case 'input':
|
||||
case 'output':
|
||||
this._ignoreFilter = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (this._header)
|
||||
{
|
||||
this._time = getCurTime();
|
||||
this._from = getFrom();
|
||||
}
|
||||
}
|
||||
_formatMsg()
|
||||
{
|
||||
let type = this._type,
|
||||
idx = this._idx,
|
||||
hasHeader = this._header,
|
||||
time = this._time,
|
||||
from = this._from,
|
||||
args = this._args;
|
||||
|
||||
let msg = '', icon;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 'log':
|
||||
case 'info':
|
||||
case 'warn':
|
||||
msg = formatMsg(args);
|
||||
break;
|
||||
case 'error':
|
||||
let err = args[0];
|
||||
icon = 'times-circle';
|
||||
err = util.isErr(args[0]) ? args[0] : new Error(err);
|
||||
msg = formatErr(err);
|
||||
break;
|
||||
case 'table':
|
||||
msg = formatTable(args);
|
||||
break;
|
||||
case 'html':
|
||||
msg = args[0];
|
||||
break;
|
||||
case 'input':
|
||||
msg = formatJs(args[0]);
|
||||
icon = 'chevron-right';
|
||||
break;
|
||||
case 'output':
|
||||
msg = formatMsg(args);
|
||||
icon = 'chevron-left';
|
||||
break;
|
||||
}
|
||||
|
||||
msg = render({msg, type, icon, idx, hasHeader, time, from});
|
||||
this.src = stringify(this._args);
|
||||
|
||||
delete this._args;
|
||||
this._formattedMsg = msg;
|
||||
}
|
||||
}
|
||||
|
||||
function formatTable(args)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
var regJsUrl = /https?:\/\/([0-9.\-A-Za-z]+)(?::(\d+))?\/[A-Z.a-z0-9/]*\.js/g;
|
||||
|
||||
function formatErr(err)
|
||||
{
|
||||
var lines = err.stack.split('\n'),
|
||||
msg = `${err.message || lines[0]}<br/>`;
|
||||
|
||||
lines = lines.filter(val => val.indexOf('eruda') < 0);
|
||||
|
||||
var stack = `<div class="eruda-stack">${lines.slice(1).join('<br/>')}</div>`;
|
||||
|
||||
return msg + stack.replace(regJsUrl, match => `<a href="${match}" target="_blank">${match}</a>`);
|
||||
}
|
||||
|
||||
function formatJs(code)
|
||||
{
|
||||
return highlight(beautify(code), 'js');
|
||||
}
|
||||
|
||||
function formatMsg(args)
|
||||
{
|
||||
if (util.isStr(args[0])) args = substituteStr(args);
|
||||
|
||||
for (let i = 0, len = args.length; i < len; i++)
|
||||
{
|
||||
let val = args[i];
|
||||
|
||||
if (util.isEl(val))
|
||||
{
|
||||
args[i] = formatEl(val);
|
||||
} else if (util.isFn(val))
|
||||
{
|
||||
args[i] = formatFn(val);
|
||||
} else if (util.isObj(val))
|
||||
{
|
||||
args[i] = formatObj(val);
|
||||
}else if (util.isUndef(val))
|
||||
{
|
||||
args[i] = 'undefined';
|
||||
} else if (util.isNull(val))
|
||||
{
|
||||
args[i] = 'null';
|
||||
} else
|
||||
{
|
||||
args[i] = util.escape(util.toStr(val));
|
||||
}
|
||||
}
|
||||
|
||||
return args.join(' ');
|
||||
}
|
||||
|
||||
function substituteStr(args)
|
||||
{
|
||||
var str = args[0],
|
||||
newStr = '';
|
||||
|
||||
args.shift();
|
||||
|
||||
for (let i = 0, len = str.length; i < len; i++)
|
||||
{
|
||||
let c = str[i];
|
||||
|
||||
if (c === '%')
|
||||
{
|
||||
i++;
|
||||
let arg = args.shift();
|
||||
switch (str[i])
|
||||
{
|
||||
case 'd':
|
||||
newStr += util.toNum(arg);
|
||||
break;
|
||||
case 's':
|
||||
newStr += util.toStr(arg);
|
||||
break;
|
||||
case 'o':
|
||||
try {
|
||||
newStr += JSON.stringify(arg);
|
||||
} catch (e) {}
|
||||
break;
|
||||
default:
|
||||
i--;
|
||||
args.unshift(arg);
|
||||
newStr += c;
|
||||
}
|
||||
} else
|
||||
{
|
||||
newStr += c;
|
||||
}
|
||||
}
|
||||
|
||||
args.unshift(newStr);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function formatObj(val)
|
||||
{
|
||||
return `${util.upperFirst(typeof val)} ${JSON.stringify(extractObj(val, true))}`;
|
||||
}
|
||||
|
||||
function formatFn(val)
|
||||
{
|
||||
return val.toString();
|
||||
}
|
||||
|
||||
function formatEl(val)
|
||||
{
|
||||
return `<pre>${highlight(beautify.html(val.outerHTML), 'html')}</pre>`;
|
||||
}
|
||||
|
||||
function getCurTime()
|
||||
{
|
||||
let d = new Date();
|
||||
|
||||
return `${padZero(d.getHours())}:${padZero(d.getMinutes())}:${padZero(d.getSeconds())}`;
|
||||
}
|
||||
|
||||
function getFrom()
|
||||
{
|
||||
let e = new Error(),
|
||||
ret = '',
|
||||
lines = e.stack.split('\n');
|
||||
|
||||
for (let i = 0, len = lines.length; i < len; i++)
|
||||
{
|
||||
ret = lines[i];
|
||||
if (ret.indexOf('winConsole') > -1 && i < len - 1)
|
||||
{
|
||||
ret = lines[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
var padZero = (num) => util.lpad(util.toStr(num), 2, '0');
|
||||
|
||||
var tpl = require('./Log.hbs');
|
||||
var render = data => tpl(data);
|
||||
|
||||
var extractObj = (obj, simple) => JSON.parse(stringify(obj, null, obj, simple));
|
||||
|
||||
20
src/Console/Log.hbs
Normal file
20
src/Console/Log.hbs
Normal file
@@ -0,0 +1,20 @@
|
||||
<li>
|
||||
{{#if hasHeader}}
|
||||
<div class="eruda-header">
|
||||
{{time}} {{from}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="eruda-{{type}} eruda-log-item" data-idx="{{idx}}">
|
||||
{{#if icon}}
|
||||
<div class="eruda-icon-container">
|
||||
<span class="eruda-icon eruda-icon-{{icon}}"></span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if showTimes}}<div class="eruda-times">{{times}}</div>{{/if}}
|
||||
<div class="eruda-log-content-wrapper">
|
||||
<div class="eruda-log-content">
|
||||
{{{msg}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -2,179 +2,64 @@ 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'
|
||||
import Log from './Log.es6'
|
||||
|
||||
export default class Logger extends util.Emitter
|
||||
{
|
||||
constructor($el, parent)
|
||||
{
|
||||
super();
|
||||
|
||||
util.evalCss(require('./Logger.scss'));
|
||||
|
||||
this._$el = $el;
|
||||
this._parent = parent;
|
||||
this._logs = [];
|
||||
this._renderLogs = [];
|
||||
this._tpl = require('./Logger.hbs');
|
||||
this._timer = {};
|
||||
this._filter = 'all';
|
||||
this._maxNum = 'infinite';
|
||||
this._displayExtraInfo = false;
|
||||
this._isUpdated = false;
|
||||
this._lastLog = {};
|
||||
this._timer = {};
|
||||
|
||||
this._bindEvent();
|
||||
}
|
||||
setMaxNum(num)
|
||||
{
|
||||
var logs = this._logs;
|
||||
|
||||
this._maxNum = num;
|
||||
if (util.isNum(num) && logs.length > num)
|
||||
{
|
||||
this._logs = logs.slice(logs.length - num);
|
||||
this._isUpdated = true;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
displayExtraInfo(flag)
|
||||
{
|
||||
this._displayExtraInfo = flag;
|
||||
}
|
||||
clear()
|
||||
maxNum(val)
|
||||
{
|
||||
this._logs = [];
|
||||
this._lastLog = {};
|
||||
this._isUpdated = true;
|
||||
var logs = this._logs;
|
||||
|
||||
this._maxNum = val;
|
||||
if (util.isNum(val) && logs.length > val)
|
||||
{
|
||||
this._logs = logs.slice(logs.length - val);
|
||||
this._isUpdated = true;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
filter(val)
|
||||
{
|
||||
this._filter = val;
|
||||
this.emit('filter', val);
|
||||
return this.render();
|
||||
}
|
||||
input(jsCode)
|
||||
{
|
||||
if (util.startWith(jsCode, ':'))
|
||||
{
|
||||
this._runCmd(jsCode.slice(1));
|
||||
|
||||
return this;
|
||||
} else if (util.startWith(jsCode, '/'))
|
||||
{
|
||||
return this.filter(new RegExp(util.escapeRegExp(jsCode.slice(1))));
|
||||
}
|
||||
|
||||
this.insert({
|
||||
type: 'input',
|
||||
ignoreFilter: true,
|
||||
isCode: true,
|
||||
icon: 'chevron-right',
|
||||
src: jsCode,
|
||||
val: jsCode
|
||||
});
|
||||
|
||||
try {
|
||||
this.output(evalJs(jsCode));
|
||||
} catch (e)
|
||||
{
|
||||
e.ignoreFilter = true;
|
||||
this.error(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
output(val)
|
||||
{
|
||||
return this.insert({
|
||||
type: 'output',
|
||||
ignoreFilter: true,
|
||||
icon: 'chevron-left',
|
||||
src: util.isObj(val) ? extractObj(val) : val,
|
||||
val: transMsg(val)
|
||||
});
|
||||
}
|
||||
dir(obj)
|
||||
{
|
||||
var src = util.isObj(obj) ? extractObj(obj) : obj,
|
||||
msg;
|
||||
|
||||
if (util.isObj(src))
|
||||
{
|
||||
msg = JSON.stringify(src, null, 4);
|
||||
msg = msg.replace(/erudaProto/g, '__proto__')
|
||||
.replace(/erudaObjAbstract/g, '__abstract__');
|
||||
|
||||
} else
|
||||
{
|
||||
msg = transMsg(src, true);
|
||||
}
|
||||
|
||||
return this.insert({
|
||||
type: 'dir',
|
||||
isCode: true,
|
||||
src,
|
||||
val: msg
|
||||
});
|
||||
}
|
||||
log(...args)
|
||||
{
|
||||
return this.insert({
|
||||
type: 'log',
|
||||
src: extractSrc(args),
|
||||
val: transMultipleMsg(args)
|
||||
});
|
||||
}
|
||||
html(val)
|
||||
{
|
||||
return this.insert({
|
||||
type: 'html',
|
||||
ignoreFilter: true,
|
||||
val
|
||||
});
|
||||
}
|
||||
error(msg)
|
||||
{
|
||||
if (util.isUndef(msg)) return;
|
||||
this.insert('log', args);
|
||||
|
||||
if (!util.isErr(msg)) msg = new Error(msg);
|
||||
return this;
|
||||
}
|
||||
dir(...args)
|
||||
{
|
||||
this.insert('dir', args);
|
||||
|
||||
return this.insert({
|
||||
type: 'error',
|
||||
ignoreFilter: msg.ignoreFilter,
|
||||
src: {
|
||||
message: msg.message || '',
|
||||
stack: msg.stack
|
||||
},
|
||||
icon: 'times-circle',
|
||||
val: errToStr(msg)
|
||||
});
|
||||
return this;
|
||||
}
|
||||
info(...args)
|
||||
table(...args)
|
||||
{
|
||||
return this.insert({
|
||||
type: 'info',
|
||||
src: extractSrc(args),
|
||||
icon: 'info-circle',
|
||||
val: transMultipleMsg(args)
|
||||
});
|
||||
}
|
||||
warn(...args)
|
||||
{
|
||||
return this.insert({
|
||||
type: 'warn',
|
||||
src: extractSrc(args),
|
||||
icon: 'exclamation-triangle',
|
||||
val: transMultipleMsg(args)
|
||||
});
|
||||
}
|
||||
filter(type)
|
||||
{
|
||||
this._filter = type;
|
||||
this.emit('filter', type);
|
||||
this._isUpdated = true;
|
||||
return this.render();
|
||||
}
|
||||
help()
|
||||
{
|
||||
return this.html(helpMsg);
|
||||
this.insert('table', args);
|
||||
|
||||
return this;
|
||||
}
|
||||
time(name)
|
||||
{
|
||||
@@ -191,107 +76,95 @@ export default class Logger extends util.Emitter
|
||||
|
||||
return this.html(`<div class="eruda-blue">${name}: ${util.now() - startTime}ms</div>`);
|
||||
}
|
||||
insert(log)
|
||||
clear()
|
||||
{
|
||||
var logs = this._logs;
|
||||
this._logs = [];
|
||||
|
||||
if (this._maxNum !== 'infinite' && logs.length >= this._maxNum) logs.shift();
|
||||
|
||||
util.defaults(log, {
|
||||
type: 'log',
|
||||
isCode: false,
|
||||
ignoreFilter: false,
|
||||
val: '',
|
||||
showTimes: false,
|
||||
times: 1
|
||||
});
|
||||
|
||||
log.src = log.src || log.val;
|
||||
|
||||
if (log.isCode)
|
||||
{
|
||||
log.val = highlight(beautify(log.val), 'js');
|
||||
} else if (log.type != 'html')
|
||||
{
|
||||
log.val = txtToHtml(log.val);
|
||||
}
|
||||
|
||||
if (this._displayExtraInfo)
|
||||
{
|
||||
log.hasHeader = true;
|
||||
log.time = getCurTime();
|
||||
log.from = getFrom();
|
||||
}
|
||||
|
||||
var lastLog = this._lastLog;
|
||||
|
||||
if (log.type !== 'html' &&
|
||||
lastLog.type === log.type &&
|
||||
lastLog.val === log.val)
|
||||
{
|
||||
lastLog.times++;
|
||||
lastLog.showTimes = true;
|
||||
if (log.time) lastLog.time = log.time;
|
||||
} else
|
||||
{
|
||||
logs.push(log);
|
||||
this._lastLog = log;
|
||||
}
|
||||
|
||||
this.emit('insert', log);
|
||||
|
||||
this._isUpdated = true;
|
||||
return this.render();
|
||||
}
|
||||
_bindEvent()
|
||||
info(...args)
|
||||
{
|
||||
var self = this;
|
||||
|
||||
this._$el.on('click', '.eruda-log-item', function ()
|
||||
{
|
||||
var idx = util.$(this).data('idx'),
|
||||
src = self._renderLogs[idx].src;
|
||||
|
||||
try {
|
||||
if (!util.isObj(src)) src = JSON.parse(src);
|
||||
self.emit('viewJson', src);
|
||||
} catch (e) {}
|
||||
});
|
||||
return this.insert('info', args);
|
||||
}
|
||||
_runCmd(cmd)
|
||||
error(...args)
|
||||
{
|
||||
switch (cmd.trim())
|
||||
return this.insert('error', args);
|
||||
}
|
||||
warn(...args)
|
||||
{
|
||||
return this.insert('warn', args);
|
||||
}
|
||||
input(jsCode)
|
||||
{
|
||||
if (util.startWith(jsCode, ':'))
|
||||
{
|
||||
case '$': return this._loadJs('jQuery');
|
||||
case '_': return this._loadJs('underscore');
|
||||
default:
|
||||
this.warn('Unknown command').help();
|
||||
this._runCmd(jsCode.slice(1));
|
||||
|
||||
return this;
|
||||
} else if (util.startWith(jsCode, '/'))
|
||||
{
|
||||
return this.filter(new RegExp(util.escapeRegExp(jsCode.slice(1))));
|
||||
}
|
||||
}
|
||||
_loadJs(name)
|
||||
{
|
||||
util.loadJs(libraries[name], (result) =>
|
||||
{
|
||||
if (result) return this.log(`${name} is loaded`);
|
||||
|
||||
this.warn(`Failed to load ${name}`);
|
||||
});
|
||||
this.insert('input', [jsCode]);
|
||||
|
||||
try {
|
||||
this.output(evalJs(jsCode));
|
||||
} catch (e)
|
||||
{
|
||||
this.error(e);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
output(val)
|
||||
{
|
||||
return this.insert('output', [val]);
|
||||
}
|
||||
html(...args)
|
||||
{
|
||||
return this.insert('html', args);
|
||||
}
|
||||
help()
|
||||
{
|
||||
return this.html(helpMsg);
|
||||
}
|
||||
render()
|
||||
{
|
||||
if (!this._parent.active || !this._isUpdated) return;
|
||||
this._isUpdated = false;
|
||||
let html = '',
|
||||
logs = this._logs;
|
||||
|
||||
var logs = this._renderLogs = this._filterLogs(this._logs);
|
||||
logs = this._renderLogs = this._filterLogs(logs);
|
||||
|
||||
for (let i = 0, len = logs.length; i < len; i++)
|
||||
{
|
||||
html += logs[i].formattedMsg;
|
||||
}
|
||||
|
||||
this._renderHtml(this._tpl({logs: logs}));
|
||||
this._scrollToBottom();
|
||||
}
|
||||
_renderHtml(html)
|
||||
{
|
||||
if (html === this._lastHtml) return;
|
||||
this._lastHtml = html;
|
||||
this._$el.html(html);
|
||||
this.scrollToBottom();
|
||||
|
||||
return this;
|
||||
}
|
||||
insert(type, args)
|
||||
{
|
||||
let logs = this._logs;
|
||||
|
||||
let log = new Log({
|
||||
type, args,
|
||||
idx: logs.length,
|
||||
header: this._displayExtraInfo
|
||||
});
|
||||
logs.push(log);
|
||||
this.render();
|
||||
|
||||
return this;
|
||||
}
|
||||
scrollToBottom()
|
||||
{
|
||||
var el = this._$el.get(0);
|
||||
|
||||
el.scrollTop = el.scrollHeight;
|
||||
}
|
||||
_filterLogs(logs)
|
||||
{
|
||||
@@ -310,11 +183,39 @@ export default class Logger extends util.Emitter
|
||||
return val.ignoreFilter || val.type === filter;
|
||||
});
|
||||
}
|
||||
_scrollToBottom()
|
||||
_loadJs(name)
|
||||
{
|
||||
var el = this._$el.get(0);
|
||||
util.loadJs(libraries[name], (result) =>
|
||||
{
|
||||
if (result) return this.log(`${name} is loaded`);
|
||||
|
||||
el.scrollTop = el.scrollHeight;
|
||||
this.warn(`Failed to load ${name}`);
|
||||
});
|
||||
}
|
||||
_runCmd(cmd)
|
||||
{
|
||||
switch (cmd.trim())
|
||||
{
|
||||
case '$': return this._loadJs('jQuery');
|
||||
case '_': return this._loadJs('underscore');
|
||||
default:
|
||||
this.warn('Unknown command').help();
|
||||
}
|
||||
}
|
||||
_bindEvent()
|
||||
{
|
||||
var self = this;
|
||||
|
||||
this._$el.on('click', '.eruda-log-item', function ()
|
||||
{
|
||||
var idx = util.$(this).data('idx'),
|
||||
src = self._renderLogs[idx].src;
|
||||
|
||||
try {
|
||||
if (!util.isObj(src)) src = JSON.parse(src);
|
||||
self.emit('viewJson', src);
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,8 +223,6 @@ var cmdList = require('./cmdList.json'),
|
||||
helpMsg = require('./help.hbs')({commands: cmdList}),
|
||||
libraries = require('./libraries.json');
|
||||
|
||||
var regJsUrl = /https?:\/\/([0-9.\-A-Za-z]+)(?::(\d+))?\/[A-Z.a-z0-9/]*\.js/g;
|
||||
|
||||
var evalJs = jsInput =>
|
||||
{
|
||||
var ret;
|
||||
@@ -336,84 +235,3 @@ var evalJs = jsInput =>
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
function errToStr(err)
|
||||
{
|
||||
var lines = err.stack.split('\n'),
|
||||
msg = `${err.message || lines[0]}<br/>`;
|
||||
|
||||
lines = lines.filter(val => val.indexOf('eruda') < 0);
|
||||
|
||||
var stack = `<div class="eruda-stack">${lines.slice(1).join('<br/>')}</div>`;
|
||||
|
||||
return msg + stack.replace(regJsUrl, match => `<a href="${match}" target="_blank">${match}</a>`);
|
||||
}
|
||||
|
||||
function transMsg(msg, noEscape)
|
||||
{
|
||||
if (util.isEl(msg))
|
||||
{
|
||||
msg = `<pre>${highlight(beautify.html(msg.outerHTML), 'html')}</pre>`;
|
||||
noEscape = true;
|
||||
} else if (util.isFn(msg))
|
||||
{
|
||||
msg = msg.toString();
|
||||
} else if (util.isObj(msg))
|
||||
{
|
||||
msg = `${util.upperFirst(typeof msg)} ${JSON.stringify(extractObj(msg, true))}`;
|
||||
} else if (util.isUndef(msg))
|
||||
{
|
||||
msg = 'undefined';
|
||||
} else if (msg === null)
|
||||
{
|
||||
msg = 'null';
|
||||
}
|
||||
|
||||
msg = util.toStr(msg);
|
||||
|
||||
if (noEscape) return msg;
|
||||
|
||||
return util.escape(msg);
|
||||
}
|
||||
|
||||
function extractSrc(args)
|
||||
{
|
||||
if (args.length !== 1) return args;
|
||||
|
||||
return util.isObj(args[0]) ? extractObj(args[0]) : args[0];
|
||||
}
|
||||
|
||||
function getCurTime()
|
||||
{
|
||||
let d = new Date();
|
||||
|
||||
return `${padZero(d.getHours())}:${padZero(d.getMinutes())}:${padZero(d.getSeconds())}`;
|
||||
}
|
||||
|
||||
function getFrom()
|
||||
{
|
||||
let e = new Error(),
|
||||
ret = '',
|
||||
lines = e.stack.split('\n');
|
||||
|
||||
for (let i = 0, len = lines.length; i < len; i++)
|
||||
{
|
||||
ret = lines[i];
|
||||
if (ret.indexOf('winConsole') > -1 && i < len - 1)
|
||||
{
|
||||
ret = lines[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
var padZero = (num) => util.lpad(util.toStr(num), 2, '0');
|
||||
|
||||
var extractObj = (obj, simple) => JSON.parse(stringify(obj, null, obj, simple));
|
||||
|
||||
var transMultipleMsg = args => args.map(val => transMsg(val)).join(' ');
|
||||
|
||||
var txtToHtml = str => str.replace(/\n/g, '<br/>')
|
||||
.replace(/\t/g, ' ');
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<ul>
|
||||
{{#each logs}}
|
||||
<li>
|
||||
{{#if hasHeader}}
|
||||
<div class="eruda-header">
|
||||
{{time}} {{from}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="eruda-{{type}} eruda-log-item" data-idx="{{@index}}">
|
||||
{{#if icon}}
|
||||
<div class="eruda-icon-container">
|
||||
<span class="eruda-icon eruda-icon-{{icon}}"></span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if showTimes}}<div class="eruda-times">{{times}}</div>{{/if}}
|
||||
<div class="eruda-log-content-wrapper">
|
||||
<div class="eruda-log-content">
|
||||
{{#if isCode}}
|
||||
<pre>{{{val}}}</pre>
|
||||
{{else}}
|
||||
{{{val}}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
@@ -1296,6 +1296,30 @@ module.exports = (function ()
|
||||
return exports;
|
||||
})();
|
||||
|
||||
/* ------------------------------ isNull ------------------------------ */
|
||||
|
||||
var isNull = _.isNull = (function ()
|
||||
{
|
||||
/* Check if value is an Null.
|
||||
*
|
||||
* |Name |Type |Desc |
|
||||
* |------|-------|-----------------------|
|
||||
* |value |* |Value to check |
|
||||
* |return|boolean|True if value is an Null|
|
||||
*
|
||||
* ```javascript
|
||||
* isNull(null); // -> true
|
||||
* ```
|
||||
*/
|
||||
|
||||
function exports(val)
|
||||
{
|
||||
return val === null;
|
||||
}
|
||||
|
||||
return exports;
|
||||
})();
|
||||
|
||||
/* ------------------------------ isRegExp ------------------------------ */
|
||||
|
||||
var isRegExp = _.isRegExp = (function ()
|
||||
|
||||
@@ -18,12 +18,47 @@ describe('log', function ()
|
||||
tool.clear().log(obj);
|
||||
expect($tool.find('.eruda-log')).toContainText('Object {"a":1}');
|
||||
});
|
||||
|
||||
it('html', function ()
|
||||
{
|
||||
tool.clear().html('<span class="color-blue">Blue</span>');
|
||||
expect($tool.find('.eruda-html')).toContainElement('span.color-blue');
|
||||
});
|
||||
|
||||
it('timer', function ()
|
||||
{
|
||||
tool.clear().time('eruda');
|
||||
tool.clear().timeEnd('eruda');
|
||||
expect($tool.find('.eruda-html')).toHaveText(/eruda: \d+ms/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('substitution', function ()
|
||||
{
|
||||
it('number', function ()
|
||||
{
|
||||
tool.clear().log('Eruda is %d', 1, 'year old');
|
||||
expect($tool.find('.eruda-log')).toContainText('Eruda is 1 year old');
|
||||
});
|
||||
|
||||
it('string', function ()
|
||||
{
|
||||
tool.clear().log('My name is %s', 'eruda');
|
||||
expect($tool.find('.eruda-log')).toContainText('My name is eruda');
|
||||
});
|
||||
|
||||
it('object', function ()
|
||||
{
|
||||
tool.clear().log('Object is %o', {a: 1});
|
||||
expect($tool.find('.eruda-log')).toContainText('Object is {"a":1}');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('filter', function ()
|
||||
{
|
||||
// Test case from https://github.com/liriliri/eruda/issues/14
|
||||
it('function', function ()
|
||||
/*it('function', function ()
|
||||
{
|
||||
tool.clear().filter(function (log)
|
||||
{
|
||||
@@ -41,5 +76,5 @@ describe('filter', function ()
|
||||
});
|
||||
tool.log(obj);
|
||||
expect($tool.find('.eruda-logs li').length).toEqual(1);
|
||||
});
|
||||
});*/
|
||||
});
|
||||
Reference in New Issue
Block a user