mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2026-05-26 07:08:08 +00:00
Fix most of things
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
__version__ = '2.0.3'
|
||||
__version__ = '2.1.0'
|
||||
|
||||
|
||||
import os
|
||||
|
||||
@@ -119,7 +119,6 @@ class TermCtlWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
sessions_secure_users = {}
|
||||
|
||||
def open(self, session):
|
||||
self.set_nodelay(True)
|
||||
self.session = session
|
||||
self.closed = False
|
||||
self.log.info('Websocket /ctl opened %r' % self)
|
||||
@@ -145,18 +144,24 @@ class TermCtlWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
# Certificate authed user
|
||||
secure_user = user
|
||||
|
||||
elif socket.local and socket.user == utils.User():
|
||||
elif socket.local and socket.user == utils.User() and not user:
|
||||
# Local to local returning browser user
|
||||
secure_user = socket.user
|
||||
elif user:
|
||||
try:
|
||||
user = utils.User(name=user)
|
||||
except LookupError:
|
||||
raise Exception('Invalid user')
|
||||
|
||||
if secure_user:
|
||||
user = secure_user.name
|
||||
if self.session in self.sessions:
|
||||
if user != self.sessions_secure_users[self.session]:
|
||||
user = secure_user
|
||||
if self.session in self.sessions and self.session in (
|
||||
self.sessions_secure_users):
|
||||
if user.name != self.sessions_secure_users[self.session]:
|
||||
# Restrict to authorized users
|
||||
raise tornado.web.HTTPError(403)
|
||||
else:
|
||||
self.sessions_secure_users[self.session] = user
|
||||
self.sessions_secure_users[self.session] = user.name
|
||||
|
||||
self.sessions[self.session].append(self)
|
||||
|
||||
@@ -192,7 +197,11 @@ class TermCtlWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
if cmd['cmd'] == 'open':
|
||||
self.create_terminal()
|
||||
else:
|
||||
try:
|
||||
Terminal.sessions[self.session].ctl(cmd)
|
||||
except Exception:
|
||||
# FF strange bug
|
||||
pass
|
||||
self.broadcast(self.session, message, self)
|
||||
|
||||
def on_close(self):
|
||||
@@ -203,6 +212,14 @@ class TermCtlWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
if self in self.sessions[self.session]:
|
||||
self.sessions[self.session].remove(self)
|
||||
|
||||
opts = tornado.options.options
|
||||
if opts.one_shot or (
|
||||
self.application.systemd and
|
||||
not sum([
|
||||
len(wsockets)
|
||||
for session, wsockets in self.sessions.items()])):
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@url(r'/ws/session/(?P<session>[^/]+)')
|
||||
class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
@@ -259,14 +276,6 @@ class TermWebSocket(Route, tornado.websocket.WebSocketHandler):
|
||||
self.log.info('Websocket /ws closed %r' % self)
|
||||
self.sessions[self.session].remove(self)
|
||||
|
||||
opts = tornado.options.options
|
||||
if opts.one_shot or (
|
||||
self.application.systemd and
|
||||
not sum([
|
||||
len(wsockets)
|
||||
for session, wsockets in self.sessions.items()])):
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
@url(r'/sessions/list.json')
|
||||
class SessionsList(Route):
|
||||
|
||||
4
butterfly/static/ext.min.js
vendored
4
butterfly/static/ext.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,5 @@
|
||||
(function() {
|
||||
var $, State, Terminal, cancel, cols, cutMessage, openTs, quit, rows, s, uuid, ws,
|
||||
slice = [].slice,
|
||||
var $, State, Terminal, cancel, cols, openTs, quit, rows, s, uuid, ws,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
cols = rows = null;
|
||||
@@ -9,11 +8,9 @@
|
||||
|
||||
openTs = (new Date()).getTime();
|
||||
|
||||
cutMessage = '\r\nCutting...... 8< ...... 8< ...... ' + '\r\nYou can release when there is no more output.' + '\r\nCutting...... 8< ...... 8< ......' + '\r\nCutting...... 8< ...... 8< ......';
|
||||
|
||||
ws = {
|
||||
shell: null,
|
||||
termctl: null
|
||||
ctl: null
|
||||
};
|
||||
|
||||
$ = document.querySelectorAll.bind(document);
|
||||
@@ -28,22 +25,8 @@
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var close, ctl, error, open, path, rootPath, send, term, wsUrl;
|
||||
var close, ctl, error, init_ctl_ws, init_shell_ws, open, path, reopenOnClose, rootPath, term, write, write_request, wsUrl;
|
||||
term = null;
|
||||
send = function(data) {
|
||||
return ws.shell.send(data);
|
||||
};
|
||||
ctl = function() {
|
||||
var args, type;
|
||||
type = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||
if (type === 'Resize') {
|
||||
return ws.termctl.send(JSON.stringify({
|
||||
cmd: 'size',
|
||||
cols: args[0],
|
||||
rows: args[1]
|
||||
}));
|
||||
}
|
||||
};
|
||||
if (location.protocol === 'https:') {
|
||||
wsUrl = 'wss://';
|
||||
} else {
|
||||
@@ -60,104 +43,88 @@
|
||||
}
|
||||
path += location.search;
|
||||
ws.shell = new WebSocket(wsUrl + '/ws' + path);
|
||||
ws.termctl = new WebSocket(wsUrl + '/ctl' + path);
|
||||
ws.ctl = new WebSocket(wsUrl + '/ctl' + path);
|
||||
open = function() {
|
||||
console.log("WebSocket open", arguments);
|
||||
if (ws.shell.readyState === WebSocket.OPEN && ws.termctl.readyState === WebSocket.OPEN) {
|
||||
term = new Terminal(document.body, send, ctl);
|
||||
if (term) {
|
||||
term.body.classList.remove('stopped');
|
||||
term.out = ws.shell.send.bind(ws.shell);
|
||||
term.out('\x03\n');
|
||||
return;
|
||||
}
|
||||
if (ws.shell.readyState === WebSocket.OPEN && ws.ctl.readyState === WebSocket.OPEN) {
|
||||
term = new Terminal(document.body, ws.shell.send.bind(ws.shell), ws.ctl.send.bind(ws.ctl));
|
||||
term.ws = ws;
|
||||
window.butterfly = term;
|
||||
ws.termctl.send(JSON.stringify({
|
||||
ws.ctl.send(JSON.stringify({
|
||||
cmd: 'open'
|
||||
}));
|
||||
ws.termctl.send(JSON.stringify({
|
||||
ws.ctl.send(JSON.stringify({
|
||||
cmd: 'size',
|
||||
cols: term.cols,
|
||||
rows: term.rows
|
||||
}));
|
||||
return openTs = (new Date()).getTime();
|
||||
openTs = (new Date()).getTime();
|
||||
}
|
||||
return console.log("WebSocket open end", arguments);
|
||||
};
|
||||
error = function() {
|
||||
return console.log("WebSocket error", arguments);
|
||||
return console.error("WebSocket error", arguments);
|
||||
};
|
||||
close = function() {
|
||||
console.log("WebSocket closed", arguments);
|
||||
if (quit) {
|
||||
return;
|
||||
}
|
||||
setTimeout(function() {
|
||||
quit = true;
|
||||
term.write('Closed');
|
||||
term.skipNextKey = true;
|
||||
term.body.classList.add('dead');
|
||||
if ((new Date()).getTime() - openTs > 60 * 1000) {
|
||||
return window.open('', '_self').close();
|
||||
}
|
||||
}, 1);
|
||||
return quit = true;
|
||||
};
|
||||
ws.shell.addEventListener('open', open);
|
||||
ws.termctl.addEventListener('open', open);
|
||||
ws.shell.addEventListener('error', error);
|
||||
ws.termctl.addEventListener('error', error);
|
||||
ws.shell.addEventListener('close', close);
|
||||
ws.termctl.addEventListener('close', close);
|
||||
ws.shell.addEventListener('message', function(e) {
|
||||
var letter;
|
||||
if (term.stop == null) {
|
||||
return term.write(e.data);
|
||||
} else {
|
||||
if (term.stop < cutMessage.length) {
|
||||
letter = cutMessage[term.stop++];
|
||||
} else {
|
||||
letter = '.';
|
||||
reopenOnClose = function() {
|
||||
if (quit) {
|
||||
return;
|
||||
}
|
||||
return term.write(letter);
|
||||
ws.shell = new WebSocket(wsUrl + '/ws' + path);
|
||||
return init_shell_ws();
|
||||
};
|
||||
write = function(data) {
|
||||
if (term) {
|
||||
return term.write(data);
|
||||
}
|
||||
});
|
||||
ws.termctl.addEventListener('message', function(e) {
|
||||
};
|
||||
write_request = function(e) {
|
||||
return setTimeout(write, 1, e.data);
|
||||
};
|
||||
ctl = function() {
|
||||
var cmd;
|
||||
cmd = JSON.parse(e.data);
|
||||
if (cmd.cmd === 'size') {
|
||||
return term.resize(cmd.cols, cmd.rows, true);
|
||||
}
|
||||
});
|
||||
addEventListener('beforeunload', function() {
|
||||
};
|
||||
init_shell_ws = function() {
|
||||
ws.shell.addEventListener('open', open);
|
||||
ws.shell.addEventListener('message', write_request);
|
||||
ws.shell.addEventListener('error', error);
|
||||
return ws.shell.addEventListener('close', reopenOnClose);
|
||||
};
|
||||
init_ctl_ws = function() {
|
||||
ws.ctl.addEventListener('open', open);
|
||||
ws.ctl.addEventListener('message', ctl);
|
||||
ws.ctl.addEventListener('error', error);
|
||||
return ws.ctl.addEventListener('close', close);
|
||||
};
|
||||
init_shell_ws();
|
||||
init_ctl_ws();
|
||||
return addEventListener('beforeunload', function() {
|
||||
if (!quit) {
|
||||
return 'This will exit the terminal session';
|
||||
}
|
||||
});
|
||||
window.bench = function(n) {
|
||||
var rnd;
|
||||
if (n == null) {
|
||||
n = 100000000;
|
||||
}
|
||||
rnd = '';
|
||||
while (rnd.length < n) {
|
||||
rnd += Math.random().toString(36).substring(2);
|
||||
}
|
||||
console.time('bench');
|
||||
console.profile('bench');
|
||||
term.write(rnd);
|
||||
console.profileEnd();
|
||||
return console.timeEnd('bench');
|
||||
};
|
||||
return window.cbench = function(n) {
|
||||
var rnd;
|
||||
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);
|
||||
}
|
||||
console.time('cbench');
|
||||
console.profile('cbench');
|
||||
term.write(rnd);
|
||||
console.profileEnd();
|
||||
return console.timeEnd('cbench');
|
||||
};
|
||||
});
|
||||
|
||||
cancel = function(ev) {
|
||||
@@ -217,7 +184,6 @@
|
||||
this.focus();
|
||||
this.startBlink();
|
||||
addEventListener('keydown', this.keyDown.bind(this));
|
||||
addEventListener('keyup', this.keyUp.bind(this));
|
||||
addEventListener('keypress', this.keyPress.bind(this));
|
||||
addEventListener('focus', this.focus.bind(this));
|
||||
addEventListener('blur', this.blur.bind(this));
|
||||
@@ -559,7 +525,7 @@
|
||||
};
|
||||
|
||||
Terminal.prototype.refresh = function(force) {
|
||||
var active, attr, ch, classes, cursor, data, fg, group, i, j, k, len, len1, len2, len3, len4, line, lines, m, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, ref5, skipnext, styles, u, x, z;
|
||||
var active, attr, ch, classes, cursor, data, fg, group, i, j, k, len, len1, len2, len3, len4, line, lines, m, n, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, ref5, skipnext, styles, u, x;
|
||||
if (force == null) {
|
||||
force = false;
|
||||
}
|
||||
@@ -575,7 +541,7 @@
|
||||
}
|
||||
newOut = '';
|
||||
ref2 = this.screen;
|
||||
for (j = o = 0, len2 = ref2.length; o < len2; j = ++o) {
|
||||
for (j = n = 0, len2 = ref2.length; n < len2; j = ++n) {
|
||||
line = ref2[j];
|
||||
if (!(line.dirty || force)) {
|
||||
continue;
|
||||
@@ -588,7 +554,7 @@
|
||||
}
|
||||
attr = this.cloneAttr(this.defAttr);
|
||||
skipnext = false;
|
||||
for (i = q = 0, ref3 = this.cols - 1; 0 <= ref3 ? q <= ref3 : q >= ref3; i = 0 <= ref3 ? ++q : --q) {
|
||||
for (i = o = 0, ref3 = this.cols - 1; 0 <= ref3 ? o <= ref3 : o >= ref3; i = 0 <= ref3 ? ++o : --o) {
|
||||
data = line.chars[i];
|
||||
if (data.html) {
|
||||
out += data.html;
|
||||
@@ -724,13 +690,13 @@
|
||||
lines = document.querySelectorAll('.line');
|
||||
if (lines.length > this.scrollback) {
|
||||
ref4 = Array.prototype.slice.call(lines, 0, lines.length - this.scrollback);
|
||||
for (u = 0, len3 = ref4.length; u < len3; u++) {
|
||||
line = ref4[u];
|
||||
for (q = 0, len3 = ref4.length; q < len3; q++) {
|
||||
line = ref4[q];
|
||||
line.remove();
|
||||
}
|
||||
ref5 = document.querySelectorAll('.group:empty');
|
||||
for (z = 0, len4 = ref5.length; z < len4; z++) {
|
||||
group = ref5[z];
|
||||
for (u = 0, len4 = ref5.length; u < len4; u++) {
|
||||
group = ref5[u];
|
||||
group.remove();
|
||||
}
|
||||
lines = document.querySelectorAll('.line');
|
||||
@@ -1407,29 +1373,15 @@
|
||||
return this.write(data + "\r\n");
|
||||
};
|
||||
|
||||
Terminal.prototype.keyUp = function(ev) {
|
||||
if (ev.keyCode === 19) {
|
||||
if (this.stop == null) {
|
||||
return;
|
||||
}
|
||||
this.body.classList.remove('stopped');
|
||||
this.stop = null;
|
||||
return this.out('\x03\n');
|
||||
}
|
||||
};
|
||||
|
||||
Terminal.prototype.keyDown = function(ev) {
|
||||
var key, ref;
|
||||
if (ev.keyCode > 15 && ev.keyCode < 19) {
|
||||
return true;
|
||||
}
|
||||
if (ev.keyCode === 19) {
|
||||
if (this.stop != null) {
|
||||
return;
|
||||
}
|
||||
this.body.classList.add('stopped');
|
||||
this.stop = 0;
|
||||
this.out('\x03');
|
||||
this.ws.shell.close();
|
||||
return false;
|
||||
}
|
||||
if ((ev.shiftKey || ev.ctrlKey) && ev.keyCode === 45) {
|
||||
@@ -1728,7 +1680,11 @@
|
||||
return;
|
||||
}
|
||||
if (!notif) {
|
||||
this.ctl('Resize', this.cols, this.rows);
|
||||
this.ctl(JSON.stringify({
|
||||
cmd: 'size',
|
||||
cols: this.cols,
|
||||
rows: this.rows
|
||||
}));
|
||||
}
|
||||
if (oldCols < this.cols) {
|
||||
i = this.screen.length;
|
||||
|
||||
6
butterfly/static/main.min.js
vendored
6
butterfly/static/main.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -73,7 +73,7 @@ class Terminal(object):
|
||||
if tornado.options.options.unsecure:
|
||||
if self.user:
|
||||
try:
|
||||
self.callee = utils.User(name=self.user)
|
||||
self.callee = self.user
|
||||
except LookupError:
|
||||
log.debug(
|
||||
"Can't switch to user %s" % self.user, exc_info=True)
|
||||
@@ -198,7 +198,7 @@ class Terminal(object):
|
||||
self.socket.local and
|
||||
self.caller == self.callee and
|
||||
server == self.callee
|
||||
) or not tornado.options.options.login:
|
||||
) and not tornado.options.options.login:
|
||||
# User has been auth with ssl or is the same user as server
|
||||
# or login is explicitly turned off
|
||||
if (
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# GNU General Public License for more details.s
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
@@ -18,13 +18,10 @@
|
||||
cols = rows = null
|
||||
quit = false
|
||||
openTs = (new Date()).getTime()
|
||||
cutMessage = '\r\nCutting...... 8< ...... 8< ...... ' +
|
||||
'\r\nYou can release when there is no more output.' +
|
||||
'\r\nCutting...... 8< ...... 8< ......' +
|
||||
'\r\nCutting...... 8< ...... 8< ......'
|
||||
|
||||
ws =
|
||||
shell: null
|
||||
termctl: null
|
||||
ctl: null
|
||||
|
||||
$ = document.querySelectorAll.bind(document)
|
||||
|
||||
@@ -36,13 +33,6 @@ uuid = ->
|
||||
|
||||
document.addEventListener 'DOMContentLoaded', ->
|
||||
term = null
|
||||
send = (data) ->
|
||||
ws.shell.send data
|
||||
|
||||
ctl = (type, args...) ->
|
||||
if type == 'Resize'
|
||||
ws.termctl.send JSON.stringify(
|
||||
cmd: 'size', cols: args[0], rows: args[1])
|
||||
|
||||
if location.protocol == 'https:'
|
||||
wsUrl = 'wss://'
|
||||
@@ -61,29 +51,38 @@ document.addEventListener 'DOMContentLoaded', ->
|
||||
path += location.search
|
||||
|
||||
ws.shell = new WebSocket wsUrl + '/ws' + path
|
||||
ws.termctl = new WebSocket wsUrl + '/ctl' + path
|
||||
ws.ctl = new WebSocket wsUrl + '/ctl' + path
|
||||
|
||||
open = ->
|
||||
console.log "WebSocket open", arguments
|
||||
if (ws.shell.readyState is WebSocket.OPEN and
|
||||
ws.termctl.readyState is WebSocket.OPEN)
|
||||
|
||||
term = new Terminal document.body, send, ctl
|
||||
if term
|
||||
term.body.classList.remove 'stopped'
|
||||
term.out = ws.shell.send.bind(ws.shell)
|
||||
term.out '\x03\n'
|
||||
return
|
||||
|
||||
if (ws.shell.readyState is WebSocket.OPEN and
|
||||
ws.ctl.readyState is WebSocket.OPEN)
|
||||
|
||||
term = new Terminal(
|
||||
document.body, ws.shell.send.bind(ws.shell), ws.ctl.send.bind(ws.ctl))
|
||||
term.ws = ws
|
||||
window.butterfly = term
|
||||
ws.termctl.send JSON.stringify(cmd: 'open')
|
||||
ws.termctl.send JSON.stringify(
|
||||
ws.ctl.send JSON.stringify(cmd: 'open')
|
||||
ws.ctl.send JSON.stringify(
|
||||
cmd: 'size', cols: term.cols, rows: term.rows)
|
||||
openTs = (new Date()).getTime()
|
||||
console.log "WebSocket open end", arguments
|
||||
|
||||
error = ->
|
||||
console.log "WebSocket error", arguments
|
||||
console.error "WebSocket error", arguments
|
||||
|
||||
close = ->
|
||||
console.log "WebSocket closed", arguments
|
||||
return if quit
|
||||
quit = true
|
||||
|
||||
setTimeout ->
|
||||
term.write 'Closed'
|
||||
# Allow quick reload
|
||||
term.skipNextKey = true
|
||||
@@ -91,57 +90,39 @@ document.addEventListener 'DOMContentLoaded', ->
|
||||
# Don't autoclose if websocket didn't last 1 minute
|
||||
if (new Date()).getTime() - openTs > 60 * 1000
|
||||
window.open('','_self').close()
|
||||
, 1
|
||||
quit = true
|
||||
|
||||
ws.shell.addEventListener 'open', open
|
||||
ws.termctl.addEventListener 'open', open
|
||||
reopenOnClose = ->
|
||||
return if quit
|
||||
ws.shell = new WebSocket wsUrl + '/ws' + path
|
||||
init_shell_ws()
|
||||
|
||||
ws.shell.addEventListener 'error', error
|
||||
ws.termctl.addEventListener 'error', error
|
||||
write = (data) ->
|
||||
if term
|
||||
term.write data
|
||||
|
||||
ws.shell.addEventListener 'close', close
|
||||
ws.termctl.addEventListener 'close', close
|
||||
write_request = (e) ->
|
||||
setTimeout write, 1, e.data
|
||||
|
||||
ws.shell.addEventListener 'message', (e) ->
|
||||
unless term.stop?
|
||||
term.write e.data
|
||||
else
|
||||
if term.stop < cutMessage.length
|
||||
letter = cutMessage[term.stop++]
|
||||
else
|
||||
letter = '.'
|
||||
term.write letter
|
||||
|
||||
ws.termctl.addEventListener 'message', (e) ->
|
||||
ctl = ->
|
||||
cmd = JSON.parse(e.data)
|
||||
if cmd.cmd is 'size'
|
||||
term.resize cmd.cols, cmd.rows, true
|
||||
|
||||
init_shell_ws = ->
|
||||
ws.shell.addEventListener 'open', open
|
||||
ws.shell.addEventListener 'message', write_request
|
||||
ws.shell.addEventListener 'error', error
|
||||
ws.shell.addEventListener 'close', reopenOnClose
|
||||
|
||||
init_ctl_ws = ->
|
||||
ws.ctl.addEventListener 'open', open
|
||||
ws.ctl.addEventListener 'message', ctl
|
||||
ws.ctl.addEventListener 'error', error
|
||||
ws.ctl.addEventListener 'close', close
|
||||
|
||||
init_shell_ws()
|
||||
init_ctl_ws()
|
||||
|
||||
addEventListener 'beforeunload', ->
|
||||
if not quit
|
||||
'This will exit the terminal session'
|
||||
|
||||
window.bench = (n=100000000) ->
|
||||
rnd = ''
|
||||
while rnd.length < n
|
||||
rnd += Math.random().toString(36).substring(2)
|
||||
|
||||
console.time('bench')
|
||||
console.profile('bench')
|
||||
term.write rnd
|
||||
console.profileEnd()
|
||||
console.timeEnd('bench')
|
||||
|
||||
|
||||
window.cbench = (n=100000000) ->
|
||||
rnd = ''
|
||||
while rnd.length < n
|
||||
rnd += "\x1b[#{30 + parseInt(Math.random() * 20)}m"
|
||||
rnd += Math.random().toString(36).substring(2)
|
||||
|
||||
console.time('cbench')
|
||||
console.profile('cbench')
|
||||
term.write rnd
|
||||
console.profileEnd()
|
||||
console.timeEnd('cbench')
|
||||
|
||||
@@ -87,7 +87,6 @@ class Terminal
|
||||
|
||||
@startBlink()
|
||||
addEventListener 'keydown', @keyDown.bind(@)
|
||||
addEventListener 'keyup', @keyUp.bind(@)
|
||||
addEventListener 'keypress', @keyPress.bind(@)
|
||||
addEventListener 'focus', @focus.bind(@)
|
||||
addEventListener 'blur', @blur.bind(@)
|
||||
@@ -1258,13 +1257,6 @@ class Terminal
|
||||
writeln: (data) ->
|
||||
@write "#{data}\r\n"
|
||||
|
||||
keyUp: (ev) ->
|
||||
if ev.keyCode is 19 # Pause break
|
||||
return unless @stop?
|
||||
@body.classList.remove 'stopped'
|
||||
@stop = null
|
||||
@out '\x03\n'
|
||||
|
||||
keyDown: (ev) ->
|
||||
# Key Resources:
|
||||
# https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent
|
||||
@@ -1272,10 +1264,9 @@ class Terminal
|
||||
return true if ev.keyCode > 15 and ev.keyCode < 19
|
||||
|
||||
if ev.keyCode is 19 # Pause break
|
||||
return if @stop?
|
||||
@body.classList.add 'stopped'
|
||||
@stop = 0
|
||||
@out '\x03'
|
||||
@ws.shell.close()
|
||||
return false
|
||||
|
||||
# Handle shift insert and ctrl insert
|
||||
@@ -1574,7 +1565,8 @@ class Terminal
|
||||
if (not x and not y) and oldCols == @cols and oldRows == @rows
|
||||
return
|
||||
|
||||
@ctl 'Resize', @cols, @rows unless notif
|
||||
@ctl(JSON.stringify(
|
||||
cmd: 'size', cols: @cols, rows: @rows)) unless notif
|
||||
|
||||
# resize cols
|
||||
if oldCols < @cols
|
||||
|
||||
Reference in New Issue
Block a user