mirror of
https://github.com/paradoxxxzero/butterfly.git
synced 2025-01-27 02:08:53 +00:00
931 lines
24 KiB
JavaScript
931 lines
24 KiB
JavaScript
// Generated by CoffeeScript 1.6.3
|
|
var $, FrontTerminal, alt, cancel, cols, ctl, ctrl, first, frontterm, quit, rows, send, state, virtual_input, worker,
|
|
__slice = [].slice;
|
|
|
|
state = {
|
|
x: null,
|
|
y: null
|
|
};
|
|
|
|
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;
|
|
}
|
|
});
|
|
|
|
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
|
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', function() {
|
|
var _this = this;
|
|
return setTimeout((function() {
|
|
return _this.focus();
|
|
}), 10);
|
|
});
|
|
addEventListener('click', function() {
|
|
return virtual_input.focus();
|
|
});
|
|
addEventListener('touchstart', function(e) {
|
|
if (e.touches.length === 1) {
|
|
return ctrl = true;
|
|
} else if (e.touches.length === 2) {
|
|
ctrl = false;
|
|
return alt = true;
|
|
} else if (e.touches.length === 3) {
|
|
ctrl = true;
|
|
return alt = true;
|
|
}
|
|
});
|
|
virtual_input.addEventListener('keydown', function(e) {
|
|
term.keyDown(e);
|
|
return true;
|
|
});
|
|
virtual_input.addEventListener('input', function(e) {
|
|
var len;
|
|
len = this.value.length;
|
|
if (len === 0) {
|
|
e.keyCode = 8;
|
|
term.keyDown(e);
|
|
this.value = '0';
|
|
return true;
|
|
}
|
|
e.keyCode = this.value.charAt(1).charCodeAt(0);
|
|
if ((ctrl || alt) && !first) {
|
|
e.keyCode = this.value.charAt(1).charCodeAt(0);
|
|
e.ctrlKey = ctrl;
|
|
e.altKey = alt;
|
|
if (e.keyCode >= 97 && e.keyCode <= 122) {
|
|
e.keyCode -= 32;
|
|
}
|
|
term.keyDown(e);
|
|
this.value = '0';
|
|
ctrl = alt = false;
|
|
return true;
|
|
}
|
|
term.keyPress(e);
|
|
first = false;
|
|
this.value = '0';
|
|
return true;
|
|
});
|
|
}
|
|
|
|
worker = new Worker('/static/javascripts/worker.js');
|
|
|
|
worker.addEventListener('message', function(e) {
|
|
switch (e.data.cmd) {
|
|
case 'refresh':
|
|
return frontterm.refresh(e.data.lines, e.data.start, e.data.end);
|
|
}
|
|
});
|
|
|
|
cols = rows = null;
|
|
|
|
quit = false;
|
|
|
|
$ = document.querySelectorAll.bind(document);
|
|
|
|
send = function(data) {
|
|
return worker.postMessage({
|
|
cmd: 'data',
|
|
data: data
|
|
});
|
|
};
|
|
|
|
ctl = function() {
|
|
var args, params, type;
|
|
type = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
|
params = args.join(',');
|
|
if (type === 'Resize') {
|
|
return worker.postMessage('R' + params);
|
|
}
|
|
};
|
|
|
|
addEventListener('beforeunload', function() {
|
|
if (!quit) {
|
|
return 'This will exit the terminal session';
|
|
}
|
|
});
|
|
|
|
cancel = function(ev) {
|
|
if (ev.preventDefault) {
|
|
ev.preventDefault();
|
|
}
|
|
if (ev.stopPropagation) {
|
|
ev.stopPropagation();
|
|
}
|
|
ev.cancelBubble = true;
|
|
return false;
|
|
};
|
|
|
|
FrontTerminal = (function() {
|
|
function FrontTerminal(parent) {
|
|
var div, i, term_size,
|
|
_this = this;
|
|
this.parent = parent;
|
|
this.context = this.parent.ownerDocument.defaultView;
|
|
this.document = this.parent.ownerDocument;
|
|
this.body = this.document.getElementsByTagName('body')[0];
|
|
this.element = this.document.createElement('div');
|
|
this.element.className = 'terminal focus';
|
|
this.element.style.outline = 'none';
|
|
this.element.setAttribute('tabindex', 0);
|
|
this.parent.appendChild(this.element);
|
|
div = this.document.createElement('div');
|
|
div.className = 'line';
|
|
this.element.appendChild(div);
|
|
this.children = [div];
|
|
this.compute_char_size();
|
|
div.style.height = this.char_size.height + 'px';
|
|
term_size = this.parent.getBoundingClientRect();
|
|
this.cols = Math.floor(term_size.width / this.char_size.width) - 1;
|
|
this.rows = Math.floor(term_size.height / this.char_size.height);
|
|
i = this.rows - 1;
|
|
while (i--) {
|
|
div = this.document.createElement('div');
|
|
div.style.height = this.char_size.height + 'px';
|
|
div.className = 'line';
|
|
this.element.appendChild(div);
|
|
this.children.push(div);
|
|
}
|
|
this.visualBell = 100;
|
|
this.cursorHidden = false;
|
|
this.queue = '';
|
|
this.defAttr = (0 << 18) | (257 << 9) | (256 << 0);
|
|
this.skipNextKey = null;
|
|
this.cursorState = 0;
|
|
this.focus();
|
|
this.startBlink();
|
|
addEventListener('keydown', this.keyDown.bind(this));
|
|
addEventListener('keypress', this.keyPress.bind(this));
|
|
addEventListener('focus', this.focus.bind(this));
|
|
addEventListener('blur', this.blur.bind(this));
|
|
addEventListener('paste', this.paste.bind(this));
|
|
addEventListener('resize', this.resize.bind(this));
|
|
if (typeof InstallTrigger !== "undefined") {
|
|
this.element.contentEditable = 'true';
|
|
this.element.addEventListener("mouseup", function(ev) {
|
|
var sel;
|
|
sel = getSelection().getRangeAt(0);
|
|
if (sel.startOffset === sel.endOffset) {
|
|
return getSelection().removeAllRanges();
|
|
}
|
|
});
|
|
}
|
|
this.initmouse();
|
|
}
|
|
|
|
FrontTerminal.prototype.compute_char_size = function() {
|
|
var test_span;
|
|
test_span = document.createElement('span');
|
|
test_span.textContent = '0123456789';
|
|
this.children[0].appendChild(test_span);
|
|
this.char_size = {
|
|
width: test_span.getBoundingClientRect().width / 10,
|
|
height: this.children[0].getBoundingClientRect().height
|
|
};
|
|
return this.children[0].removeChild(test_span);
|
|
};
|
|
|
|
FrontTerminal.prototype.focus = function() {
|
|
if (this.sendFocus) {
|
|
this.send('\x1b[I');
|
|
}
|
|
this.showCursor();
|
|
this.element.classList.add('focus');
|
|
return this.element.classList.remove('blur');
|
|
};
|
|
|
|
FrontTerminal.prototype.blur = function() {
|
|
this.cursorState = 1;
|
|
if (this.sendFocus) {
|
|
this.send('\x1b[O');
|
|
}
|
|
this.element.classList.add('blur');
|
|
return this.element.classList.remove('focus');
|
|
};
|
|
|
|
FrontTerminal.prototype.paste = function(ev) {
|
|
if (ev.clipboardData) {
|
|
this.send(ev.clipboardData.getData('text/plain'));
|
|
} else if (this.context.clipboardData) {
|
|
this.send(this.context.clipboardData.getData('Text'));
|
|
}
|
|
return cancel(ev);
|
|
};
|
|
|
|
FrontTerminal.prototype.initmouse = function() {
|
|
var encode, getButton, getCoords, pressed, sendButton, sendEvent, sendMove,
|
|
_this = this;
|
|
pressed = 32;
|
|
sendButton = function(ev) {
|
|
var button, pos;
|
|
button = getButton(ev);
|
|
pos = getCoords(ev);
|
|
if (!pos) {
|
|
return;
|
|
}
|
|
sendEvent(button, pos);
|
|
switch (ev.type) {
|
|
case "mousedown":
|
|
return pressed = button;
|
|
case "mouseup":
|
|
return pressed = 32;
|
|
}
|
|
};
|
|
sendMove = function(ev) {
|
|
var button, pos;
|
|
button = pressed;
|
|
pos = getCoords(ev);
|
|
if (!pos) {
|
|
return;
|
|
}
|
|
button += 32;
|
|
return sendEvent(button, pos);
|
|
};
|
|
encode = function(data, ch) {
|
|
if (!_this.utfMouse) {
|
|
if (ch === 255) {
|
|
return data.push(0);
|
|
}
|
|
if (ch > 127) {
|
|
ch = 127;
|
|
}
|
|
return data.push(ch);
|
|
} else {
|
|
if (ch === 2047) {
|
|
return data.push(0);
|
|
}
|
|
if (ch < 127) {
|
|
return data.push(ch);
|
|
} else {
|
|
if (ch > 2047) {
|
|
ch = 2047;
|
|
}
|
|
data.push(0xC0 | (ch >> 6));
|
|
return data.push(0x80 | (ch & 0x3F));
|
|
}
|
|
}
|
|
};
|
|
sendEvent = function(button, pos) {
|
|
var data;
|
|
if (_this.urxvtMouse) {
|
|
pos.x -= 32;
|
|
pos.y -= 32;
|
|
pos.x++;
|
|
pos.y++;
|
|
_this.send("\x1b[" + button + ";" + pos.x + ";" + pos.y + "M");
|
|
return;
|
|
}
|
|
if (_this.sgrMouse) {
|
|
pos.x -= 32;
|
|
pos.y -= 32;
|
|
_this.send("\x1b[<" + ((button & 3) === 3 ? button & ~3 : button) + ";" + pos.x + ";" + pos.y + ((button & 3) === 3 ? "m" : "M"));
|
|
return;
|
|
}
|
|
data = [];
|
|
encode(data, button);
|
|
encode(data, pos.x);
|
|
encode(data, pos.y);
|
|
return _this.send("\x1b[M" + String.fromCharCode.apply(String, data));
|
|
};
|
|
getButton = function(ev) {
|
|
var button, meta, mod, shift;
|
|
switch (ev.type) {
|
|
case "mousedown":
|
|
button = ev.button != null ? +ev.button : (ev.which != null ? ev.which - 1 : null);
|
|
break;
|
|
case "mouseup":
|
|
button = 3;
|
|
break;
|
|
case "wheel":
|
|
button = ev.deltaY < 0 ? 64 : 65;
|
|
}
|
|
shift = ev.shiftKey ? 4 : 0;
|
|
meta = ev.metaKey ? 8 : 0;
|
|
ctrl = ev.ctrlKey ? 16 : 0;
|
|
mod = shift | meta | ctrl;
|
|
if (_this.vt200Mouse) {
|
|
mod &= ctrl;
|
|
} else {
|
|
if (!_this.normalMouse) {
|
|
mod = 0;
|
|
}
|
|
}
|
|
return (32 + (mod << 2)) + button;
|
|
};
|
|
getCoords = function(ev) {
|
|
var el, h, w, x, y;
|
|
x = ev.pageX;
|
|
y = ev.pageY;
|
|
el = _this.element;
|
|
while (el && el !== _this.document.documentElement) {
|
|
x -= el.offsetLeft;
|
|
y -= el.offsetTop;
|
|
el = "offsetParent" in el ? el.offsetParent : el.parentNode;
|
|
}
|
|
w = _this.element.clientWidth;
|
|
h = _this.element.clientHeight;
|
|
x = Math.ceil((x / w) * _this.cols);
|
|
y = Math.ceil((y / h) * _this.rows);
|
|
if (x < 0) {
|
|
x = 0;
|
|
}
|
|
if (x > _this.cols) {
|
|
x = _this.cols;
|
|
}
|
|
if (y < 0) {
|
|
y = 0;
|
|
}
|
|
if (y > _this.rows) {
|
|
y = _this.rows;
|
|
}
|
|
x += 32;
|
|
y += 32;
|
|
return {
|
|
x: x,
|
|
y: y,
|
|
type: ev.type
|
|
};
|
|
};
|
|
addEventListener("mousedown", function(ev) {
|
|
var up;
|
|
if (!_this.mouseEvents) {
|
|
return;
|
|
}
|
|
sendButton(ev);
|
|
if (_this.vt200Mouse) {
|
|
sendButton({
|
|
__proto__: ev,
|
|
type: "mouseup"
|
|
});
|
|
return cancel(ev);
|
|
}
|
|
if (_this.normalMouse) {
|
|
addEventListener("mousemove", sendMove.bind(_this));
|
|
}
|
|
if (!_this.x10Mouse) {
|
|
addEventListener("mouseup", up = function(ev) {
|
|
sendButton(ev);
|
|
if (_this.normalMouse) {
|
|
removeEventListener("mousemove", sendMove);
|
|
}
|
|
removeEventListener("mouseup", up);
|
|
return cancel(ev);
|
|
});
|
|
}
|
|
return cancel(ev);
|
|
});
|
|
return addEventListener("wheel", function(ev) {
|
|
if (_this.mouseEvents) {
|
|
if (_this.x10Mouse) {
|
|
return;
|
|
}
|
|
sendButton(ev);
|
|
} else {
|
|
if (_this.applicationKeypad) {
|
|
return;
|
|
}
|
|
_this.scrollDisp(ev.deltaY > 0 ? 5 : -5);
|
|
}
|
|
return cancel(ev);
|
|
});
|
|
};
|
|
|
|
FrontTerminal.prototype.refresh = function(lines, start, end) {
|
|
var attr, bg, ch, classes, data, fg, flags, i, line, out, parent, row, width, x, y;
|
|
if (end - start >= this.rows / 3) {
|
|
parent = this.element.parentNode;
|
|
if (parent != null) {
|
|
parent.removeChild(this.element);
|
|
}
|
|
}
|
|
width = this.cols;
|
|
y = start;
|
|
if (end >= lines.length) {
|
|
end = lines.length - 1;
|
|
}
|
|
while (y <= end) {
|
|
row = y;
|
|
line = lines[row];
|
|
out = "";
|
|
if (y === this.y && (this.ydisp === this.ybase || this.selectMode) && !this.cursorHidden) {
|
|
x = this.x;
|
|
} else {
|
|
x = -Infinity;
|
|
}
|
|
attr = this.defAttr;
|
|
i = 0;
|
|
while (i < width) {
|
|
data = line[i][0];
|
|
ch = line[i][1];
|
|
if (data !== attr) {
|
|
if (attr !== this.defAttr) {
|
|
out += "</span>";
|
|
}
|
|
if (data !== this.defAttr) {
|
|
classes = [];
|
|
out += "<span ";
|
|
bg = data & 0x1ff;
|
|
fg = (data >> 9) & 0x1ff;
|
|
flags = data >> 18;
|
|
if (flags & 1) {
|
|
classes.push("bold");
|
|
}
|
|
if (flags & 2) {
|
|
classes.push("underline");
|
|
}
|
|
if (flags & 4) {
|
|
classes.push("blink");
|
|
}
|
|
if (flags & 8) {
|
|
classes.push("reverse-video");
|
|
}
|
|
if (flags & 16) {
|
|
classes.push("invisible");
|
|
}
|
|
if (flags & 1 && fg < 8) {
|
|
fg += 8;
|
|
}
|
|
classes.push("bg-color-" + bg);
|
|
classes.push("fg-color-" + fg);
|
|
out += "class=\"";
|
|
out += classes.join(" ");
|
|
out += "\">";
|
|
}
|
|
}
|
|
if (i === x) {
|
|
out += "<span class=\"" + (this.cursorState ? "reverse-video " : "") + "cursor\">";
|
|
}
|
|
if (ch.length > 1) {
|
|
out += ch;
|
|
} else {
|
|
switch (ch) {
|
|
case "&":
|
|
out += "&";
|
|
break;
|
|
case "<":
|
|
out += "<";
|
|
break;
|
|
case ">":
|
|
out += ">";
|
|
break;
|
|
default:
|
|
if (ch <= " ") {
|
|
out += " ";
|
|
} else {
|
|
if (("\uff00" < ch && ch < "\uffef")) {
|
|
i++;
|
|
}
|
|
out += ch;
|
|
}
|
|
}
|
|
}
|
|
if (i === x) {
|
|
out += "</span>";
|
|
}
|
|
attr = data;
|
|
i++;
|
|
}
|
|
if (attr !== this.defAttr) {
|
|
out += "</span>";
|
|
}
|
|
this.children[y].innerHTML = out;
|
|
y++;
|
|
}
|
|
return parent != null ? parent.appendChild(this.element) : void 0;
|
|
};
|
|
|
|
FrontTerminal.prototype._cursorBlink = function() {
|
|
var cursor;
|
|
this.cursorState ^= 1;
|
|
cursor = this.element.querySelector(".cursor");
|
|
if (!cursor) {
|
|
return;
|
|
}
|
|
if (cursor.classList.contains("reverse-video")) {
|
|
return cursor.classList.remove("reverse-video");
|
|
} else {
|
|
return cursor.classList.add("reverse-video");
|
|
}
|
|
};
|
|
|
|
FrontTerminal.prototype.showCursor = function() {};
|
|
|
|
FrontTerminal.prototype.startBlink = function() {
|
|
var _this = this;
|
|
if (!this.cursorBlink) {
|
|
return;
|
|
}
|
|
this._blinker = function() {
|
|
return _this._cursorBlink();
|
|
};
|
|
return this._blink = setInterval(this._blinker, 500);
|
|
};
|
|
|
|
FrontTerminal.prototype.refreshBlink = function() {
|
|
if (!this.cursorBlink) {
|
|
return;
|
|
}
|
|
clearInterval(this._blink);
|
|
return this._blink = setInterval(this._blinker, 500);
|
|
};
|
|
|
|
FrontTerminal.prototype.scrollDisp = function(disp) {
|
|
this.ydisp += disp;
|
|
if (this.ydisp > this.ybase) {
|
|
return this.ydisp = this.ybase;
|
|
} else {
|
|
if (this.ydisp < 0) {
|
|
return this.ydisp = 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
FrontTerminal.prototype.keyDown = function(ev) {
|
|
var key,
|
|
_this = this;
|
|
if (ev.keyCode > 15 && ev.keyCode < 19) {
|
|
return true;
|
|
}
|
|
if ((ev.shiftKey || ev.ctrlKey) && ev.keyCode === 45) {
|
|
return true;
|
|
}
|
|
if (ev.altKey && ev.keyCode === 90 && !this.skipNextKey) {
|
|
this.skipNextKey = true;
|
|
this.element.classList.add('skip');
|
|
return cancel(ev);
|
|
}
|
|
if (this.skipNextKey) {
|
|
this.skipNextKey = false;
|
|
this.element.classList.remove('skip');
|
|
return true;
|
|
}
|
|
switch (ev.keyCode) {
|
|
case 8:
|
|
key = ev.altKey ? "\x1b" : "";
|
|
if (ev.shiftKey) {
|
|
key += "\x08";
|
|
break;
|
|
}
|
|
key += "\x7f";
|
|
break;
|
|
case 9:
|
|
if (ev.shiftKey) {
|
|
key = "\x1b[Z";
|
|
break;
|
|
}
|
|
key = "\t";
|
|
break;
|
|
case 13:
|
|
key = "\r";
|
|
break;
|
|
case 27:
|
|
key = "\x1b";
|
|
break;
|
|
case 37:
|
|
if (this.applicationCursor) {
|
|
key = "\x1bOD";
|
|
break;
|
|
}
|
|
if (ev.shiftKey) {
|
|
return true;
|
|
}
|
|
key = "\x1b[D";
|
|
break;
|
|
case 39:
|
|
if (this.applicationCursor) {
|
|
key = "\x1bOC";
|
|
break;
|
|
}
|
|
if (ev.shiftKey) {
|
|
return true;
|
|
}
|
|
key = "\x1b[C";
|
|
break;
|
|
case 38:
|
|
if (this.applicationCursor) {
|
|
key = "\x1bOA";
|
|
break;
|
|
}
|
|
if (ev.ctrlKey) {
|
|
this.scrollDisp(-1);
|
|
return cancel(ev);
|
|
} else if (ev.shiftKey) {
|
|
return true;
|
|
} else {
|
|
key = "\x1b[A";
|
|
}
|
|
break;
|
|
case 40:
|
|
if (this.applicationCursor) {
|
|
key = "\x1bOB";
|
|
break;
|
|
}
|
|
if (ev.ctrlKey) {
|
|
this.scrollDisp(1);
|
|
return cancel(ev);
|
|
} else if (ev.shiftKey) {
|
|
return true;
|
|
} else {
|
|
key = "\x1b[B";
|
|
}
|
|
break;
|
|
case 46:
|
|
key = "\x1b[3~";
|
|
break;
|
|
case 45:
|
|
key = "\x1b[2~";
|
|
break;
|
|
case 36:
|
|
if (this.applicationKeypad) {
|
|
key = "\x1bOH";
|
|
break;
|
|
}
|
|
key = "\x1bOH";
|
|
break;
|
|
case 35:
|
|
if (this.applicationKeypad) {
|
|
key = "\x1bOF";
|
|
break;
|
|
}
|
|
key = "\x1bOF";
|
|
break;
|
|
case 33:
|
|
if (ev.shiftKey) {
|
|
this.scrollDisp(-(this.rows - 1));
|
|
return cancel(ev);
|
|
} else {
|
|
key = "\x1b[5~";
|
|
}
|
|
break;
|
|
case 34:
|
|
if (ev.shiftKey) {
|
|
this.scrollDisp(this.rows - 1);
|
|
return cancel(ev);
|
|
} else {
|
|
key = "\x1b[6~";
|
|
}
|
|
break;
|
|
case 112:
|
|
key = "\x1bOP";
|
|
break;
|
|
case 113:
|
|
key = "\x1bOQ";
|
|
break;
|
|
case 114:
|
|
key = "\x1bOR";
|
|
break;
|
|
case 115:
|
|
key = "\x1bOS";
|
|
break;
|
|
case 116:
|
|
key = "\x1b[15~";
|
|
break;
|
|
case 117:
|
|
key = "\x1b[17~";
|
|
break;
|
|
case 118:
|
|
key = "\x1b[18~";
|
|
break;
|
|
case 119:
|
|
key = "\x1b[19~";
|
|
break;
|
|
case 120:
|
|
key = "\x1b[20~";
|
|
break;
|
|
case 121:
|
|
key = "\x1b[21~";
|
|
break;
|
|
case 122:
|
|
key = "\x1b[23~";
|
|
break;
|
|
case 123:
|
|
key = "\x1b[24~";
|
|
break;
|
|
default:
|
|
if (ev.ctrlKey) {
|
|
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
|
if (this.screenKeys) {
|
|
if (!this.prefixMode && !this.selectMode && ev.keyCode === 65) {
|
|
this.enterPrefix();
|
|
return cancel(ev);
|
|
}
|
|
}
|
|
if (this.prefixMode && ev.keyCode === 86) {
|
|
this.leavePrefix();
|
|
return;
|
|
}
|
|
if ((this.prefixMode || this.selectMode) && ev.keyCode === 67) {
|
|
if (this.visualMode) {
|
|
setTimeout((function() {
|
|
_this.leaveVisual();
|
|
}), 1);
|
|
}
|
|
return;
|
|
}
|
|
key = String.fromCharCode(ev.keyCode - 64);
|
|
} else if (ev.keyCode === 32) {
|
|
key = String.fromCharCode(0);
|
|
} else if (ev.keyCode >= 51 && ev.keyCode <= 55) {
|
|
key = String.fromCharCode(ev.keyCode - 51 + 27);
|
|
} else if (ev.keyCode === 56) {
|
|
key = String.fromCharCode(127);
|
|
} else if (ev.keyCode === 219) {
|
|
key = String.fromCharCode(27);
|
|
} else {
|
|
if (ev.keyCode === 221) {
|
|
key = String.fromCharCode(29);
|
|
}
|
|
}
|
|
} else if (ev.altKey) {
|
|
if (ev.keyCode >= 65 && ev.keyCode <= 90) {
|
|
key = "\x1b" + String.fromCharCode(ev.keyCode + 32);
|
|
} else if (ev.keyCode === 192) {
|
|
key = "\x1b`";
|
|
} else {
|
|
if (ev.keyCode >= 48 && ev.keyCode <= 57) {
|
|
key = "\x1b" + (ev.keyCode - 48);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (ev.keyCode >= 37 && ev.keyCode <= 40) {
|
|
if (ev.ctrlKey) {
|
|
key = key.slice(0, -1) + "1;5" + key.slice(-1);
|
|
} else if (ev.altKey) {
|
|
key = key.slice(0, -1) + "1;3" + key.slice(-1);
|
|
} else {
|
|
if (ev.shiftKey) {
|
|
key = key.slice(0, -1) + "1;4" + key.slice(-1);
|
|
}
|
|
}
|
|
}
|
|
if (!key) {
|
|
return true;
|
|
}
|
|
if (this.prefixMode) {
|
|
this.leavePrefix();
|
|
return cancel(ev);
|
|
}
|
|
if (this.selectMode) {
|
|
this.keySelect(ev, key);
|
|
return cancel(ev);
|
|
}
|
|
this.showCursor();
|
|
this.handler(key);
|
|
return cancel(ev);
|
|
};
|
|
|
|
FrontTerminal.prototype.keyPress = function(ev) {
|
|
var key;
|
|
if (this.skipNextKey === false) {
|
|
this.skipNextKey = null;
|
|
return true;
|
|
}
|
|
cancel(ev);
|
|
if (ev.charCode) {
|
|
key = ev.charCode;
|
|
} else if (ev.which == null) {
|
|
key = ev.keyCode;
|
|
} else if (ev.which !== 0 && ev.charCode !== 0) {
|
|
key = ev.which;
|
|
} else {
|
|
return false;
|
|
}
|
|
if (!key || ev.ctrlKey || ev.altKey || ev.metaKey) {
|
|
return false;
|
|
}
|
|
key = String.fromCharCode(key);
|
|
this.showCursor();
|
|
this.handler(key);
|
|
return false;
|
|
};
|
|
|
|
FrontTerminal.prototype.handler = function(data) {
|
|
return worker.postMessage({
|
|
cmd: 'data',
|
|
data: data
|
|
});
|
|
};
|
|
|
|
FrontTerminal.prototype.send = function(data) {
|
|
var _this = this;
|
|
if (!this.queue) {
|
|
setTimeout((function() {
|
|
_this.handler(_this.queue);
|
|
_this.queue = "";
|
|
}), 1);
|
|
}
|
|
return this.queue += data;
|
|
};
|
|
|
|
FrontTerminal.prototype.bell = function() {
|
|
var _this = this;
|
|
if (!this.visualBell) {
|
|
return;
|
|
}
|
|
this.element.classList.add("bell");
|
|
return setTimeout((function() {
|
|
return _this.element.classList.remove("bell");
|
|
}), this.visualBell);
|
|
};
|
|
|
|
FrontTerminal.prototype.resize = function() {
|
|
var el, j, line, old_cols, old_rows, term_size, _results, _results1;
|
|
old_cols = this.cols;
|
|
old_rows = this.rows;
|
|
term_size = this.parent.getBoundingClientRect();
|
|
this.cols = Math.floor(term_size.width / this.char_size.width) - 1;
|
|
this.rows = Math.floor(term_size.height / this.char_size.height);
|
|
if (old_cols === this.cols && old_rows === this.rows) {
|
|
return;
|
|
}
|
|
this.ctl('Resize', this.cols, this.rows);
|
|
j = old_rows;
|
|
if (j < this.rows) {
|
|
el = this.element;
|
|
_results = [];
|
|
while (j++ < this.rows) {
|
|
if (this.children.length < this.rows) {
|
|
line = this.document.createElement("div");
|
|
line.className = 'line';
|
|
line.style.height = this.char_size.height + 'px';
|
|
el.appendChild(line);
|
|
_results.push(this.children.push(line));
|
|
} else {
|
|
_results.push(void 0);
|
|
}
|
|
}
|
|
return _results;
|
|
} else if (j > this.rows) {
|
|
_results1 = [];
|
|
while (j-- > this.rows) {
|
|
if (this.children.length > this.rows) {
|
|
el = this.children.pop();
|
|
if (!el) {
|
|
continue;
|
|
}
|
|
_results1.push(el.parentNode.removeChild(el));
|
|
} else {
|
|
_results1.push(void 0);
|
|
}
|
|
}
|
|
return _results1;
|
|
}
|
|
};
|
|
|
|
FrontTerminal.prototype.get_html_height_in_lines = function(html) {
|
|
var html_height, temp_node;
|
|
temp_node = document.createElement("div");
|
|
temp_node.innerHTML = html;
|
|
this.element.appendChild(temp_node);
|
|
html_height = temp_node.getBoundingClientRect().height;
|
|
this.element.removeChild(temp_node);
|
|
return Math.ceil(html_height / this.char_size.height);
|
|
};
|
|
|
|
return FrontTerminal;
|
|
|
|
})();
|
|
|
|
frontterm = new FrontTerminal($('#wrapper')[0], send, ctl);
|
|
|
|
worker.postMessage({
|
|
cmd: 'init',
|
|
cols: frontterm.cols,
|
|
rows: frontterm.rows,
|
|
wsurl: 'ws://' + document.location.host + '/ws' + location.pathname
|
|
});
|