mirror of
https://github.com/liriliri/eruda.git
synced 2026-04-01 10:18:35 +08:00
Dev: Console
This commit is contained in:
72
src/Console/Console.es6
Normal file
72
src/Console/Console.es6
Normal file
@@ -0,0 +1,72 @@
|
||||
import Log from './Log.es6'
|
||||
import util from '../util'
|
||||
|
||||
require('!style!css!sass!./Console.scss');
|
||||
|
||||
export default class Console
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
this.name = 'console';
|
||||
}
|
||||
init($el)
|
||||
{
|
||||
this._$el = $el;
|
||||
|
||||
this._appendTpl();
|
||||
this._initLog();
|
||||
this._bindEvent();
|
||||
}
|
||||
_appendTpl()
|
||||
{
|
||||
var $el = this._$el;
|
||||
|
||||
$el.append(require('./Console.hbs')());
|
||||
this._$logs = $el.find('.logs');
|
||||
this._$jsInput = $el.find('.js-input');
|
||||
}
|
||||
_initLog()
|
||||
{
|
||||
this._log = new Log(this._$logs);
|
||||
this._log.overrideConsole().catchGlobalErr();
|
||||
}
|
||||
_bindEvent()
|
||||
{
|
||||
var $jsInput = this._$jsInput,
|
||||
log = this._log;
|
||||
|
||||
$jsInput.on('keyup', (e) =>
|
||||
{
|
||||
e = e.origEvent;
|
||||
|
||||
if (e.keyCode === 13)
|
||||
{
|
||||
var jsInput = $jsInput.val();
|
||||
|
||||
if (util.trim(jsInput) === '') return;
|
||||
|
||||
log.input(jsInput);
|
||||
try {
|
||||
log.output(this._evalJs(jsInput));
|
||||
} catch (e)
|
||||
{
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
$jsInput.val('');
|
||||
}
|
||||
});
|
||||
}
|
||||
_evalJs(jsInput)
|
||||
{
|
||||
var log = this._log;
|
||||
|
||||
function clear()
|
||||
{
|
||||
log.clear();
|
||||
}
|
||||
|
||||
return eval(jsInput);
|
||||
}
|
||||
}
|
||||
|
||||
2
src/Console/Console.hbs
Normal file
2
src/Console/Console.hbs
Normal file
@@ -0,0 +1,2 @@
|
||||
<div class="logs"></div>
|
||||
<input class="js-input" type="text"></input>
|
||||
16
src/Console/Console.scss
Normal file
16
src/Console/Console.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
#eruda { .dev-tools { .tools {
|
||||
.console {
|
||||
.js-input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
box-shadow: 0 -1px 0 0 #ccc;
|
||||
line-height: 30px;
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
} } }
|
||||
119
src/Console/Log.es6
Normal file
119
src/Console/Log.es6
Normal file
@@ -0,0 +1,119 @@
|
||||
import util from '../util'
|
||||
|
||||
require('!style!css!sass!./Log.scss');
|
||||
|
||||
function errToStr(err)
|
||||
{
|
||||
var lines = err.stack.split('\n');
|
||||
|
||||
var msg = lines[0] + '<br/>',
|
||||
stack = '<div class="stack">' + lines.slice(1).join('<br/>') + '</div>';
|
||||
|
||||
return msg + stack;
|
||||
}
|
||||
|
||||
export default class Log
|
||||
{
|
||||
constructor($el)
|
||||
{
|
||||
this._$el = $el;
|
||||
this._logs = [];
|
||||
this._tpl = require('./Log.hbs');
|
||||
}
|
||||
overrideConsole()
|
||||
{
|
||||
var self = this;
|
||||
|
||||
window.console.log = (msg) =>
|
||||
{
|
||||
self.log(msg);
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
catchGlobalErr()
|
||||
{
|
||||
var self = this;
|
||||
|
||||
window.onerror = (errMsg, url, lineNum, column, errObj) =>
|
||||
{
|
||||
self.error(errObj);
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
clear()
|
||||
{
|
||||
this._logs = [];
|
||||
|
||||
this._render();
|
||||
}
|
||||
input(msg)
|
||||
{
|
||||
this._logs.push({
|
||||
type: 'input',
|
||||
val: msg
|
||||
});
|
||||
|
||||
this._render();
|
||||
|
||||
return this;
|
||||
}
|
||||
output(msg)
|
||||
{
|
||||
if (util.isUndef(msg)) msg = 'undefined';
|
||||
|
||||
this._logs.push({
|
||||
type: 'output',
|
||||
val: msg
|
||||
});
|
||||
|
||||
this._render();
|
||||
|
||||
return this;
|
||||
}
|
||||
log(msg)
|
||||
{
|
||||
this._logs.push({
|
||||
type: 'log',
|
||||
val: msg
|
||||
});
|
||||
|
||||
this._render();
|
||||
|
||||
return this;
|
||||
}
|
||||
error(msg)
|
||||
{
|
||||
if (util.isErr(msg))
|
||||
{
|
||||
msg = errToStr(msg);
|
||||
} else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
this._logs.push({
|
||||
type: 'error',
|
||||
val: msg
|
||||
});
|
||||
|
||||
this._render();
|
||||
|
||||
return this;
|
||||
}
|
||||
_render()
|
||||
{
|
||||
this._$el.html(this._tpl({
|
||||
logs: this._logs
|
||||
}));
|
||||
|
||||
this._scrollToBottom();
|
||||
}
|
||||
_scrollToBottom()
|
||||
{
|
||||
var el = this._$el.get(0);
|
||||
|
||||
el.scrollTop = el.scrollHeight;
|
||||
}
|
||||
}
|
||||
5
src/Console/Log.hbs
Normal file
5
src/Console/Log.hbs
Normal file
@@ -0,0 +1,5 @@
|
||||
<ul>
|
||||
{{#each logs}}
|
||||
<li class="{{type}}">{{{val}}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
22
src/Console/Log.scss
Normal file
22
src/Console/Log.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
#eruda { .dev-tools { .tools { .console {
|
||||
.logs {
|
||||
height: calc(100% - 30px);
|
||||
overflow: scroll;
|
||||
li {
|
||||
padding: 4px;
|
||||
&.log, &.output {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
&.error {
|
||||
background: #fff0f0;
|
||||
color: #ff0000;
|
||||
border-top: 1px solid #ffd7d7;
|
||||
border-bottom: 1px solid #ffd7d7;
|
||||
.stack {
|
||||
color: #000;
|
||||
padding-left: 1.2em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} } } }
|
||||
54
src/DevTools/DevTools.es6
Normal file
54
src/DevTools/DevTools.es6
Normal file
@@ -0,0 +1,54 @@
|
||||
import NavBar from './NavBar.es6'
|
||||
|
||||
require('!style!css!sass!./DevTools.scss');
|
||||
|
||||
export default class DevTools
|
||||
{
|
||||
constructor($parent)
|
||||
{
|
||||
this._$parent = $parent;
|
||||
this._isShow = false;
|
||||
this._tools = {};
|
||||
|
||||
this._appendTpl();
|
||||
this._initNavBar();
|
||||
}
|
||||
_appendTpl()
|
||||
{
|
||||
var $parent = this._$parent;
|
||||
|
||||
$parent.append(require('./DevTools.hbs')());
|
||||
|
||||
this._$el = $parent.find('.dev-tools');
|
||||
this._$tools = this._$el.find('.tools');
|
||||
}
|
||||
_initNavBar()
|
||||
{
|
||||
this._navBar = new NavBar(this._$el.find('.nav-bar'));
|
||||
}
|
||||
show()
|
||||
{
|
||||
this._isShow = true;
|
||||
|
||||
this._$el.addClass('show').rmClass('hide');
|
||||
}
|
||||
hide()
|
||||
{
|
||||
this._isShow = false;
|
||||
|
||||
this._$el.addClass('hide').rmClass('show');
|
||||
setTimeout(() => this._$el.rmClass('hide'), 3000);
|
||||
}
|
||||
toggle()
|
||||
{
|
||||
this._isShow ? this.hide() : this.show();
|
||||
}
|
||||
add(tool)
|
||||
{
|
||||
var name = tool.name;
|
||||
|
||||
this._$tools.append('<div class="' + name + ' tool"></div>');
|
||||
tool.init(this._$tools.find('.' + name));
|
||||
this._tools[name] = tool;
|
||||
}
|
||||
}
|
||||
4
src/DevTools/DevTools.hbs
Normal file
4
src/DevTools/DevTools.hbs
Normal file
@@ -0,0 +1,4 @@
|
||||
<div class="dev-tools">
|
||||
<div class="nav-bar"></div>
|
||||
<div class="tools"></div>
|
||||
</div>
|
||||
51
src/DevTools/DevTools.scss
Normal file
51
src/DevTools/DevTools.scss
Normal file
@@ -0,0 +1,51 @@
|
||||
#eruda {
|
||||
.dev-tools {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
z-index: 500;
|
||||
display: none;
|
||||
&.show {
|
||||
display: block;
|
||||
animation: show-menu .3s linear both;
|
||||
}
|
||||
&.hide {
|
||||
display: block;
|
||||
animation: hide-menu .3s linear both;
|
||||
}
|
||||
.tools {
|
||||
height: calc(100% - 50px);
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: scroll;
|
||||
.tool {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes show-menu {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes hide-menu {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
37
src/DevTools/HomeBtn.es6
Normal file
37
src/DevTools/HomeBtn.es6
Normal file
@@ -0,0 +1,37 @@
|
||||
import util from '../util'
|
||||
|
||||
var Draggabilly = require('draggabilly');
|
||||
|
||||
require('!style!css!sass!./HomeBtn.scss');
|
||||
|
||||
export default class HomeBtn
|
||||
{
|
||||
constructor($parent)
|
||||
{
|
||||
this._$parent = $parent;
|
||||
|
||||
this._appendTpl();
|
||||
this._makeDraggable();
|
||||
this._bindEvent();
|
||||
|
||||
util.Emitter.mixin(this);
|
||||
}
|
||||
_appendTpl()
|
||||
{
|
||||
var $parent = this._$parent;
|
||||
|
||||
$parent.append(require('./HomeBtn.hbs')());
|
||||
|
||||
this._$el = $parent.find('.home-btn');
|
||||
}
|
||||
_bindEvent()
|
||||
{
|
||||
this._draggabilly.on('staticClick', () => this.emit('click') );
|
||||
}
|
||||
_makeDraggable()
|
||||
{
|
||||
this._draggabilly = new Draggabilly(this._$el.get(0), {
|
||||
containment: true
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -3,12 +3,12 @@
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
opacity: 0.5;
|
||||
opacity: 0.3;
|
||||
border-radius: 10px;
|
||||
padding-top: 10px;
|
||||
position: relative;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
z-index: 1000;
|
||||
transition: opacity .3s;
|
||||
.circle {
|
||||
15
src/DevTools/NavBar.es6
Normal file
15
src/DevTools/NavBar.es6
Normal file
@@ -0,0 +1,15 @@
|
||||
require('!style!css!sass!./NavBar.scss');
|
||||
|
||||
export default class NavBar
|
||||
{
|
||||
constructor($el)
|
||||
{
|
||||
this._$el = $el;
|
||||
|
||||
this.render();
|
||||
}
|
||||
render()
|
||||
{
|
||||
this._$el.append(require('./NavBar.hbs')());
|
||||
}
|
||||
}
|
||||
3
src/DevTools/NavBar.hbs
Normal file
3
src/DevTools/NavBar.hbs
Normal file
@@ -0,0 +1,3 @@
|
||||
<ul>
|
||||
<li class="active">Console</li>
|
||||
</ul>
|
||||
21
src/DevTools/NavBar.scss
Normal file
21
src/DevTools/NavBar.scss
Normal file
@@ -0,0 +1,21 @@
|
||||
#eruda { .dev-tools {
|
||||
.nav-bar {
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 0 0 #ccc;
|
||||
ul {
|
||||
display: flex;
|
||||
li {
|
||||
float: left;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
flex-grow: 1;
|
||||
&.active {
|
||||
color: #76a2ee;
|
||||
border-bottom: 3px solid #76a2ee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
0
src/Elements/Elements.es6
Normal file
0
src/Elements/Elements.es6
Normal file
0
src/Network/Network.es6
Normal file
0
src/Network/Network.es6
Normal file
0
src/Settings/Settings.es6
Normal file
0
src/Settings/Settings.es6
Normal file
@@ -1,28 +0,0 @@
|
||||
import util from '../util'
|
||||
|
||||
require('!style!css!sass!./style.scss');
|
||||
|
||||
export default class HomeBtn {
|
||||
constructor($parent)
|
||||
{
|
||||
this.$parent = $parent;
|
||||
|
||||
this.appendTpl();
|
||||
this.bindEvent();
|
||||
}
|
||||
appendTpl()
|
||||
{
|
||||
var $parent = this.$parent;
|
||||
|
||||
$parent.append(require('./template.hbs')());
|
||||
|
||||
this.$el = $parent.find('.home-btn');
|
||||
}
|
||||
bindEvent()
|
||||
{
|
||||
this.$el.on('click', function ()
|
||||
{
|
||||
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,6 @@
|
||||
import HomeBtn from './HomeBtn/index.es6'
|
||||
import HomeBtn from './DevTools/HomeBtn.es6'
|
||||
import DevTools from './DevTools/DevTools.es6'
|
||||
import Console from './Console/Console.es6'
|
||||
import util from './util'
|
||||
|
||||
require('!style!css!sass!./style.scss');
|
||||
@@ -10,7 +12,16 @@ var isDebugMode = /eruda=true/.test(window.location.search);
|
||||
if (isDebugMode)
|
||||
{
|
||||
appendContainer();
|
||||
|
||||
var devTools = new DevTools($container);
|
||||
|
||||
var homeBtn = new HomeBtn($container);
|
||||
|
||||
homeBtn.on('click', () => devTools.toggle());
|
||||
|
||||
devTools.add(new Console());
|
||||
|
||||
devTools.show();
|
||||
}
|
||||
|
||||
function appendContainer()
|
||||
|
||||
@@ -5,8 +5,14 @@
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: Lora, Times, serif;
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
pointer-events: all;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
}
|
||||
}
|
||||
215
src/util.js
215
src/util.js
@@ -175,6 +175,24 @@ module.exports = (function ()
|
||||
return has;
|
||||
})();
|
||||
|
||||
/* ------------------------------ slice ------------------------------ */
|
||||
|
||||
var slice;
|
||||
|
||||
_.slice = (function ()
|
||||
{
|
||||
// TODO
|
||||
|
||||
var arrProto = Array.prototype;
|
||||
|
||||
slice = function (arr, start, end)
|
||||
{
|
||||
return arrProto.slice.call(arr, start, end);
|
||||
};
|
||||
|
||||
return slice;
|
||||
})();
|
||||
|
||||
/* ------------------------------ _createAssigner ------------------------------ */
|
||||
|
||||
var _createAssigner;
|
||||
@@ -491,6 +509,25 @@ module.exports = (function ()
|
||||
return isStr;
|
||||
})();
|
||||
|
||||
/* ------------------------------ isErr ------------------------------ */
|
||||
|
||||
var isErr;
|
||||
|
||||
_.isErr = (function ()
|
||||
{
|
||||
// TODO
|
||||
|
||||
/* function
|
||||
* isErr: Checks if value is an Error.
|
||||
* value(*): The value to check.
|
||||
* return(boolean): Returns true if value is an error object, else false.
|
||||
*/
|
||||
|
||||
isErr = function (val) { return objToStr(val) === '[object Error]' };
|
||||
|
||||
return isErr;
|
||||
})();
|
||||
|
||||
/* ------------------------------ isFn ------------------------------ */
|
||||
|
||||
var isFn;
|
||||
@@ -540,6 +577,49 @@ module.exports = (function ()
|
||||
return isMatch;
|
||||
})();
|
||||
|
||||
/* ------------------------------ ltrim ------------------------------ */
|
||||
|
||||
var ltrim;
|
||||
|
||||
_.ltrim = (function ()
|
||||
{
|
||||
// TODO
|
||||
|
||||
var regSpace = /^\s+/;
|
||||
|
||||
ltrim = function (str, chars)
|
||||
{
|
||||
if (chars == null) return str.replace(regSpace, '');
|
||||
|
||||
var start = 0,
|
||||
len = str.length,
|
||||
charLen = chars.length,
|
||||
found = true,
|
||||
i, c;
|
||||
|
||||
while (found && start < len)
|
||||
{
|
||||
found = false;
|
||||
i = -1;
|
||||
c = str.charAt(start);
|
||||
|
||||
while (++i < charLen)
|
||||
{
|
||||
if (c === chars[i])
|
||||
{
|
||||
found = true;
|
||||
start++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (start >= len) ? '' : str.substr(start, len);
|
||||
};
|
||||
|
||||
return ltrim;
|
||||
})();
|
||||
|
||||
/* ------------------------------ matcher ------------------------------ */
|
||||
|
||||
var matcher;
|
||||
@@ -748,6 +828,79 @@ module.exports = (function ()
|
||||
return Class;
|
||||
})();
|
||||
|
||||
/* ------------------------------ Emitter ------------------------------ */
|
||||
|
||||
var Emitter;
|
||||
|
||||
_.Emitter = (function ()
|
||||
{
|
||||
|
||||
Emitter = Class({
|
||||
initialize: function ()
|
||||
{
|
||||
this._events = this._events || {};
|
||||
},
|
||||
on: function (event, listener)
|
||||
{
|
||||
this._events[event] = this._events[event] || [];
|
||||
this._events[event].push(listener);
|
||||
|
||||
return this;
|
||||
},
|
||||
off: function (event, listener)
|
||||
{
|
||||
if (!has(this._events, event)) return;
|
||||
|
||||
this._events[event].splice(this._events[event].indexOf(listener), 1);
|
||||
|
||||
return this;
|
||||
},
|
||||
once: function (event, listener)
|
||||
{
|
||||
var fired = false;
|
||||
|
||||
function g()
|
||||
{
|
||||
this.off(event, g);
|
||||
if (!fired)
|
||||
{
|
||||
fired = true;
|
||||
listener.apply(this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
this.on(event, g);
|
||||
|
||||
return this;
|
||||
},
|
||||
emit: function (event)
|
||||
{
|
||||
if (!has(this._events, event)) return;
|
||||
|
||||
var args = slice(arguments, 1);
|
||||
|
||||
each(this._events[event], function (val)
|
||||
{
|
||||
val.apply(this, args);
|
||||
}, this);
|
||||
|
||||
return this;
|
||||
}
|
||||
}, {
|
||||
mixin: function (obj)
|
||||
{
|
||||
each(['on', 'off', 'once', 'emit'], function (val)
|
||||
{
|
||||
obj[val] = Emitter.prototype[val];
|
||||
});
|
||||
|
||||
obj._events = obj._events || {};
|
||||
}
|
||||
});
|
||||
|
||||
return Emitter;
|
||||
})();
|
||||
|
||||
/* ------------------------------ delegate ------------------------------ */
|
||||
|
||||
var delegate;
|
||||
@@ -1586,5 +1739,67 @@ module.exports = (function ()
|
||||
return $;
|
||||
})();
|
||||
|
||||
/* ------------------------------ rtrim ------------------------------ */
|
||||
|
||||
var rtrim;
|
||||
|
||||
_.rtrim = (function ()
|
||||
{
|
||||
// TODO
|
||||
|
||||
var regSpace = /\s+$/;
|
||||
|
||||
rtrim = function (str, chars)
|
||||
{
|
||||
if (chars == null) return str.replace(regSpace, '');
|
||||
|
||||
var end = str.length - 1,
|
||||
charLen = chars.length,
|
||||
found = true,
|
||||
i, c;
|
||||
|
||||
while (found && end >= 0)
|
||||
{
|
||||
found = false;
|
||||
i = -1;
|
||||
c = str.charAt(end);
|
||||
|
||||
while (++i < charLen)
|
||||
{
|
||||
if (c === chars[i])
|
||||
{
|
||||
found = true;
|
||||
end--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (end >= 0) ? str.substring(0, end + 1) : '';
|
||||
};
|
||||
|
||||
return rtrim;
|
||||
})();
|
||||
|
||||
/* ------------------------------ trim ------------------------------ */
|
||||
|
||||
var trim;
|
||||
|
||||
_.trim = (function ()
|
||||
{
|
||||
// TODO
|
||||
|
||||
var regSpace = /^\s+|\s+$/g;
|
||||
|
||||
trim = function (str, chars)
|
||||
{
|
||||
if (chars == null) return str.replace(regSpace, '');
|
||||
|
||||
return ltrim(rtrim(str, chars), chars);
|
||||
};
|
||||
|
||||
return trim;
|
||||
})();
|
||||
|
||||
return _;
|
||||
})();
|
||||
Reference in New Issue
Block a user