Dev: Console

This commit is contained in:
surunzi
2016-03-10 00:25:15 +08:00
parent 38662fe6aa
commit 3ccc538a49
25 changed files with 1511 additions and 47 deletions

72
src/Console/Console.es6 Normal file
View 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
View File

@@ -0,0 +1,2 @@
<div class="logs"></div>
<input class="js-input" type="text"></input>

16
src/Console/Console.scss Normal file
View 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
View 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
View File

@@ -0,0 +1,5 @@
<ul>
{{#each logs}}
<li class="{{type}}">{{{val}}}</li>
{{/each}}
</ul>

22
src/Console/Log.scss Normal file
View 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
View 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;
}
}

View File

@@ -0,0 +1,4 @@
<div class="dev-tools">
<div class="nav-bar"></div>
<div class="tools"></div>
</div>

View 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
View 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
});
}
};

View File

@@ -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
View 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
View File

@@ -0,0 +1,3 @@
<ul>
<li class="active">Console</li>
</ul>

21
src/DevTools/NavBar.scss Normal file
View 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;
}
}
}
}
} }

View File

0
src/Network/Network.es6 Normal file
View File

View File

View 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 ()
{
});
}
};

View File

@@ -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()

View File

@@ -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;
}
}

View File

@@ -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 _;
})();