mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2026-05-31 01:19:40 +00:00
Start term.js rewrite
This commit is contained in:
24
butterfly/static/coffees/backsel.coffee
Normal file
24
butterfly/static/coffees/backsel.coffee
Normal file
@@ -0,0 +1,24 @@
|
||||
state =
|
||||
x: null
|
||||
y: null
|
||||
|
||||
document.addEventListener 'keydown', (e) ->
|
||||
if e.shiftKey and (37 <= e.keyCode <= 40)
|
||||
if state.y == null
|
||||
state.y = term.ybase + term.y
|
||||
if e.keyCode == 38
|
||||
state.y--
|
||||
if state.y < term.ybase
|
||||
state.y = term.ybase
|
||||
else if e.keyCode == 40
|
||||
state.y++
|
||||
if state.y > term.ybase + term.y
|
||||
state.y = term.ybase + term.y
|
||||
|
||||
term.emit('data', ' \x0b\x15')
|
||||
if state.y != term.ybase + term.y
|
||||
term.emit('data', term.grabText(0, term.cols - 1, state.y, state.y).replace('\n', ''))
|
||||
e.stopPropagation()
|
||||
return false
|
||||
else
|
||||
state.x = state.y = null
|
||||
@@ -1,74 +1,7 @@
|
||||
try
|
||||
document.createEvent("TouchEvent")
|
||||
virtual_input = true
|
||||
catch e
|
||||
virtual_input = false
|
||||
|
||||
term = ws = null
|
||||
cols = rows = null
|
||||
quit = false
|
||||
|
||||
if virtual_input
|
||||
ctrl = false
|
||||
alt = false
|
||||
first = true
|
||||
virtual_input = document.createElement 'input'
|
||||
virtual_input.type = 'password'
|
||||
virtual_input.style.position = 'fixed'
|
||||
virtual_input.style.top = 0
|
||||
virtual_input.style.left = 0
|
||||
virtual_input.style.border = 'none'
|
||||
virtual_input.style.outline = 'none'
|
||||
virtual_input.style.opacity = 0
|
||||
virtual_input.value = '0'
|
||||
document.body.appendChild virtual_input
|
||||
|
||||
virtual_input.addEventListener 'blur', ->
|
||||
setTimeout((=> @focus()), 10)
|
||||
|
||||
addEventListener 'click', ->
|
||||
virtual_input.focus()
|
||||
|
||||
addEventListener 'touchstart', (e) ->
|
||||
if e.touches.length == 1
|
||||
ctrl = true
|
||||
else if e.touches.length == 2
|
||||
ctrl = false
|
||||
alt = true
|
||||
else if e.touches.length == 3
|
||||
ctrl = true
|
||||
alt = true
|
||||
|
||||
virtual_input.addEventListener 'keydown', (e) ->
|
||||
term.keyDown(e)
|
||||
return true
|
||||
|
||||
virtual_input.addEventListener 'input', (e) ->
|
||||
len = @value.length
|
||||
|
||||
if len == 0
|
||||
e.keyCode = 8
|
||||
term.keyDown e
|
||||
@value = '0'
|
||||
return true
|
||||
|
||||
e.keyCode = @value.charAt(1).charCodeAt(0)
|
||||
|
||||
if (ctrl or alt) and not first
|
||||
e.keyCode = @value.charAt(1).charCodeAt(0)
|
||||
e.ctrlKey = ctrl
|
||||
e.altKey = alt
|
||||
if e.keyCode >= 97 && e.keyCode <= 122
|
||||
e.keyCode -= 32
|
||||
term.keyDown e
|
||||
@value = '0'
|
||||
ctrl = alt = false
|
||||
return true
|
||||
|
||||
term.keyPress e
|
||||
first = false
|
||||
@value = '0'
|
||||
true
|
||||
|
||||
$ = document.querySelectorAll.bind(document)
|
||||
|
||||
@@ -80,7 +13,7 @@ ws.onopen = ->
|
||||
term = new Terminal(
|
||||
visualBell: 100
|
||||
screenKeys: true
|
||||
scrollback: -1
|
||||
scrollback: 100000
|
||||
)
|
||||
term.on "data", (data) ->
|
||||
ws.send 'SH|' + data
|
||||
@@ -93,6 +26,9 @@ ws.onopen = ->
|
||||
resize()
|
||||
|
||||
|
||||
ws.onerror = -> console.log "WebSocket error", arguments
|
||||
ws.onmessage = (e) -> term.write e.data
|
||||
|
||||
ws.onclose = ->
|
||||
if term
|
||||
term.destroy()
|
||||
@@ -100,10 +36,6 @@ ws.onclose = ->
|
||||
quit = true
|
||||
open('','_self').close()
|
||||
|
||||
ws.onerror = -> console.log "WebSocket error", arguments
|
||||
ws.onmessage = (e) ->
|
||||
term.write event.data
|
||||
|
||||
addEventListener 'beforeunload', ->
|
||||
if not quit
|
||||
'This will exit the terminal session'
|
||||
@@ -133,3 +65,23 @@ addEventListener 'resize', resize = ->
|
||||
div.style.height = eh + 'px'
|
||||
|
||||
ws.send "RS|#{cols},#{rows}"
|
||||
|
||||
bench = (n=100000000) ->
|
||||
rnd = ''
|
||||
while rnd.length < n
|
||||
rnd += Math.random().toString(36).substring(2)
|
||||
|
||||
t0 = (new Date()).getTime()
|
||||
term.write rnd
|
||||
console.log "#{n} chars in #{(new Date()).getTime() - t0} ms"
|
||||
|
||||
|
||||
cbench = (n=100000000) ->
|
||||
rnd = ''
|
||||
while rnd.length < n
|
||||
rnd += "\x1b[#{30 + parseInt(Math.random() * 20)}m"
|
||||
rnd += Math.random().toString(36).substring(2)
|
||||
|
||||
t0 = (new Date()).getTime()
|
||||
term.write rnd
|
||||
console.log "#{n} chars + colors in #{(new Date()).getTime() - t0} ms"
|
||||
|
||||
1067
butterfly/static/coffees/term.coffee
Normal file
1067
butterfly/static/coffees/term.coffee
Normal file
File diff suppressed because it is too large
Load Diff
68
butterfly/static/coffees/virtual_input.coffee
Normal file
68
butterfly/static/coffees/virtual_input.coffee
Normal file
@@ -0,0 +1,68 @@
|
||||
try
|
||||
document.createEvent("TouchEvent")
|
||||
virtual_input = true
|
||||
catch e
|
||||
virtual_input = false
|
||||
|
||||
|
||||
if virtual_input
|
||||
ctrl = false
|
||||
alt = false
|
||||
first = true
|
||||
virtual_input = document.createElement 'input'
|
||||
virtual_input.type = 'password'
|
||||
virtual_input.style.position = 'fixed'
|
||||
virtual_input.style.top = 0
|
||||
virtual_input.style.left = 0
|
||||
virtual_input.style.border = 'none'
|
||||
virtual_input.style.outline = 'none'
|
||||
virtual_input.style.opacity = 0
|
||||
virtual_input.value = '0'
|
||||
document.body.appendChild virtual_input
|
||||
|
||||
virtual_input.addEventListener 'blur', ->
|
||||
setTimeout((=> @focus()), 10)
|
||||
|
||||
addEventListener 'click', ->
|
||||
virtual_input.focus()
|
||||
|
||||
addEventListener 'touchstart', (e) ->
|
||||
if e.touches.length == 1
|
||||
ctrl = true
|
||||
else if e.touches.length == 2
|
||||
ctrl = false
|
||||
alt = true
|
||||
else if e.touches.length == 3
|
||||
ctrl = true
|
||||
alt = true
|
||||
|
||||
virtual_input.addEventListener 'keydown', (e) ->
|
||||
term.keyDown(e)
|
||||
return true
|
||||
|
||||
virtual_input.addEventListener 'input', (e) ->
|
||||
len = @value.length
|
||||
|
||||
if len == 0
|
||||
e.keyCode = 8
|
||||
term.keyDown e
|
||||
@value = '0'
|
||||
return true
|
||||
|
||||
e.keyCode = @value.charAt(1).charCodeAt(0)
|
||||
|
||||
if (ctrl or alt) and not first
|
||||
e.keyCode = @value.charAt(1).charCodeAt(0)
|
||||
e.ctrlKey = ctrl
|
||||
e.altKey = alt
|
||||
if e.keyCode >= 97 && e.keyCode <= 122
|
||||
e.keyCode -= 32
|
||||
term.keyDown e
|
||||
@value = '0'
|
||||
ctrl = alt = false
|
||||
return true
|
||||
|
||||
term.keyPress e
|
||||
first = false
|
||||
@value = '0'
|
||||
true
|
||||
@@ -1,5 +1,114 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
var $, alt, cols, ctrl, e, first, quit, resize, rows, term, virtual_input, ws, ws_url;
|
||||
var $, alt, bench, cbench, cols, ctrl, e, first, quit, resize, rows, state, term, virtual_input, ws, ws_url;
|
||||
|
||||
term = ws = null;
|
||||
|
||||
cols = rows = null;
|
||||
|
||||
quit = false;
|
||||
|
||||
$ = document.querySelectorAll.bind(document);
|
||||
|
||||
ws_url = 'ws://' + document.location.host + '/ws' + location.pathname;
|
||||
|
||||
ws = new WebSocket(ws_url);
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log("WebSocket open", arguments);
|
||||
term = new Terminal({
|
||||
visualBell: 100,
|
||||
screenKeys: true,
|
||||
scrollback: 100000
|
||||
});
|
||||
term.on("data", function(data) {
|
||||
return ws.send('SH|' + data);
|
||||
});
|
||||
term.on("title", function(title) {
|
||||
return document.title = title;
|
||||
});
|
||||
term.open($('main')[0]);
|
||||
$('.terminal')[0].style = '';
|
||||
return resize();
|
||||
};
|
||||
|
||||
ws.onerror = function() {
|
||||
return console.log("WebSocket error", arguments);
|
||||
};
|
||||
|
||||
ws.onmessage = function(e) {
|
||||
return term.write(e.data);
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
if (term) {
|
||||
term.destroy();
|
||||
}
|
||||
console.log("WebSocket closed", arguments);
|
||||
quit = true;
|
||||
return open('', '_self').close();
|
||||
};
|
||||
|
||||
addEventListener('beforeunload', function() {
|
||||
if (!quit) {
|
||||
return 'This will exit the terminal session';
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener('resize', resize = function() {
|
||||
var div, eh, ew, fake_term, fake_term_div, fake_term_line, main, main_bb, _i, _len, _ref;
|
||||
main = $('main')[0];
|
||||
fake_term = document.createElement('div');
|
||||
fake_term.className = 'terminal test';
|
||||
fake_term_div = document.createElement('div');
|
||||
fake_term_line = document.createElement('span');
|
||||
fake_term_line.textContent = '0123456789';
|
||||
fake_term_div.appendChild(fake_term_line);
|
||||
fake_term.appendChild(fake_term_div);
|
||||
main.appendChild(fake_term);
|
||||
ew = fake_term_line.getBoundingClientRect().width;
|
||||
eh = fake_term_div.getBoundingClientRect().height;
|
||||
main.removeChild(fake_term);
|
||||
main_bb = main.getBoundingClientRect();
|
||||
cols = Math.floor(10 * main_bb.width / ew) - 1;
|
||||
rows = Math.floor(main_bb.height / eh);
|
||||
console.log("Computed " + cols + " cols and " + rows + " rows from ", main_bb, ew, eh);
|
||||
term.resize(cols, rows);
|
||||
_ref = $('.terminal div');
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
div = _ref[_i];
|
||||
div.style.height = eh + 'px';
|
||||
}
|
||||
return ws.send("RS|" + cols + "," + rows);
|
||||
});
|
||||
|
||||
bench = function(n) {
|
||||
var rnd, t0;
|
||||
if (n == null) {
|
||||
n = 100000000;
|
||||
}
|
||||
rnd = '';
|
||||
while (rnd.length < n) {
|
||||
rnd += Math.random().toString(36).substring(2);
|
||||
}
|
||||
t0 = (new Date()).getTime();
|
||||
term.write(rnd);
|
||||
return console.log("" + n + " chars in " + ((new Date()).getTime() - t0) + " ms");
|
||||
};
|
||||
|
||||
cbench = function(n) {
|
||||
var rnd, t0;
|
||||
if (n == null) {
|
||||
n = 100000000;
|
||||
}
|
||||
rnd = '';
|
||||
while (rnd.length < n) {
|
||||
rnd += "\x1b[" + (30 + parseInt(Math.random() * 20)) + "m";
|
||||
rnd += Math.random().toString(36).substring(2);
|
||||
}
|
||||
t0 = (new Date()).getTime();
|
||||
term.write(rnd);
|
||||
return console.log("" + n + " chars + colors in " + ((new Date()).getTime() - t0) + " ms");
|
||||
};
|
||||
|
||||
try {
|
||||
document.createEvent("TouchEvent");
|
||||
@@ -9,12 +118,6 @@ try {
|
||||
virtual_input = false;
|
||||
}
|
||||
|
||||
term = ws = null;
|
||||
|
||||
cols = rows = null;
|
||||
|
||||
quit = false;
|
||||
|
||||
if (virtual_input) {
|
||||
ctrl = false;
|
||||
alt = false;
|
||||
@@ -82,76 +185,35 @@ if (virtual_input) {
|
||||
});
|
||||
}
|
||||
|
||||
$ = document.querySelectorAll.bind(document);
|
||||
|
||||
ws_url = 'ws://' + document.location.host + '/ws' + location.pathname;
|
||||
|
||||
ws = new WebSocket(ws_url);
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log("WebSocket open", arguments);
|
||||
term = new Terminal({
|
||||
visualBell: 100,
|
||||
screenKeys: true,
|
||||
scrollback: -1
|
||||
});
|
||||
term.on("data", function(data) {
|
||||
return ws.send('SH|' + data);
|
||||
});
|
||||
term.on("title", function(title) {
|
||||
return document.title = title;
|
||||
});
|
||||
term.open($('main')[0]);
|
||||
$('.terminal')[0].style = '';
|
||||
return resize();
|
||||
state = {
|
||||
x: null,
|
||||
y: null
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
if (term) {
|
||||
term.destroy();
|
||||
}
|
||||
console.log("WebSocket closed", arguments);
|
||||
quit = true;
|
||||
return open('', '_self').close();
|
||||
};
|
||||
|
||||
ws.onerror = function() {
|
||||
return console.log("WebSocket error", arguments);
|
||||
};
|
||||
|
||||
ws.onmessage = function(e) {
|
||||
return term.write(event.data);
|
||||
};
|
||||
|
||||
addEventListener('beforeunload', function() {
|
||||
if (!quit) {
|
||||
return 'This will exit the terminal session';
|
||||
document.addEventListener('keydown', function(e) {
|
||||
var _ref;
|
||||
if (e.shiftKey && ((37 <= (_ref = e.keyCode) && _ref <= 40))) {
|
||||
if (state.y === null) {
|
||||
state.y = term.ybase + term.y;
|
||||
}
|
||||
if (e.keyCode === 38) {
|
||||
state.y--;
|
||||
if (state.y < term.ybase) {
|
||||
state.y = term.ybase;
|
||||
}
|
||||
} else if (e.keyCode === 40) {
|
||||
state.y++;
|
||||
if (state.y > term.ybase + term.y) {
|
||||
state.y = term.ybase + term.y;
|
||||
}
|
||||
}
|
||||
term.emit('data', ' \x0b\x15');
|
||||
if (state.y !== term.ybase + term.y) {
|
||||
term.emit('data', term.grabText(0, term.cols - 1, state.y, state.y).replace('\n', ''));
|
||||
}
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
} else {
|
||||
return state.x = state.y = null;
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener('resize', resize = function() {
|
||||
var div, eh, ew, fake_term, fake_term_div, fake_term_line, main, main_bb, _i, _len, _ref;
|
||||
main = $('main')[0];
|
||||
fake_term = document.createElement('div');
|
||||
fake_term.className = 'terminal test';
|
||||
fake_term_div = document.createElement('div');
|
||||
fake_term_line = document.createElement('span');
|
||||
fake_term_line.textContent = '0123456789';
|
||||
fake_term_div.appendChild(fake_term_line);
|
||||
fake_term.appendChild(fake_term_div);
|
||||
main.appendChild(fake_term);
|
||||
ew = fake_term_line.getBoundingClientRect().width;
|
||||
eh = fake_term_div.getBoundingClientRect().height;
|
||||
main.removeChild(fake_term);
|
||||
main_bb = main.getBoundingClientRect();
|
||||
cols = Math.floor(10 * main_bb.width / ew) - 1;
|
||||
rows = Math.floor(main_bb.height / eh);
|
||||
console.log("Computed " + cols + " cols and " + rows + " rows from ", main_bb, ew, eh);
|
||||
term.resize(cols, rows);
|
||||
_ref = $('.terminal div');
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
div = _ref[_i];
|
||||
div.style.height = eh + 'px';
|
||||
}
|
||||
return ws.send("RS|" + cols + "," + rows);
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ def get_env(inode):
|
||||
if '=' in keyval:
|
||||
key, val = keyval.split('=', 1)
|
||||
env[key] = val
|
||||
return env
|
||||
return env
|
||||
|
||||
|
||||
class Socket(object):
|
||||
|
||||
Reference in New Issue
Block a user