Move to xterm.js for CJK and IME support (#22)

This commit is contained in:
Shuanglei Tao
2016-11-09 20:02:04 +08:00
committed by GitHub
parent 24c3f2a880
commit e0e6d89870
14 changed files with 1802 additions and 700 deletions

109
html/js/app.js Normal file
View File

@@ -0,0 +1,109 @@
(function() {
var terminalContainer = document.getElementById('terminal-container'),
httpsEnabled = window.location.protocol == "https:",
url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws',
protocols = ["tty"],
autoReconnect = -1,
term, pingTimer;
var openWs = function() {
var ws = new WebSocket(url, protocols);
ws.onopen = function(event) {
if (typeof tty_auth_token !== 'undefined') {
ws.send(JSON.stringify({AuthToken: tty_auth_token}));
}
pingTimer = setInterval(sendPing, 30 * 1000, ws);
if (typeof term !== 'undefined') {
term.destroy();
}
term = new Terminal();
term.on('resize', function (size) {
if (ws.readyState === WebSocket.OPEN) {
ws.send("2" + JSON.stringify({columns: size.cols, rows: size.rows}));
}
setTimeout(function() {
term.showOverlay(size.cols + 'x' + size.rows);
}, 500);
});
term.on("data", function(data) {
if (ws.readyState === WebSocket.OPEN) {
ws.send("0" + data);
}
});
window.onresize = function(event) {
term.fit();
};
while (terminalContainer.firstChild) {
terminalContainer.removeChild(terminalContainer.firstChild);
}
term.open(terminalContainer);
term.fit();
term.focus();
};
ws.onmessage = function(event) {
var data = event.data.slice(1);
switch(event.data[0]) {
case '0':
term.write(decodeURIComponent(escape(window.atob(data))));
break;
case '1': // pong
break;
case '2':
document.title = data;
break;
case '3':
var preferences = JSON.parse(data);
Object.keys(preferences).forEach(function(key) {
console.log("Setting " + key + ": " + preferences[key]);
term.setOption(key, preferences[key]);
});
break;
case '4':
autoReconnect = JSON.parse(data);
console.log("Enabling reconnect: " + autoReconnect + " seconds")
break;
}
};
ws.onclose = function(event) {
if (term) {
term.off('data');
term.off('resize');
term.showOverlay("Connection Closed", null);
}
clearInterval(pingTimer);
if (autoReconnect > 0) {
setTimeout(openWs, autoReconnect * 1000);
}
};
ws.onerror = function(event) {
var errorNode = document.createElement('div');
errorNode.style.cssText = [
"color: red",
"background-color: white",
"font-size: x-large",
"opacity: 0.75",
"text-align: center",
"margin: 1em",
"padding: 0.2em",
"border: 0.1em dotted #ccc"
].join(";");
errorNode.textContent = "Websocket handshake failed!";
terminalContainer.insertBefore(errorNode, terminalContainer.firstChild);
};
};
var sendPing = function(ws) {
ws.send("1");
};
openWs();
})()

View File

@@ -0,0 +1,56 @@
// ported from hterm.Terminal.prototype.showOverlay
Terminal.prototype.showOverlay = function(msg, timeout) {
if (!this.overlayNode_) {
if (!this.element)
return;
this.overlayNode_ = document.createElement('div');
this.overlayNode_.style.cssText = (
'border-radius: 15px;' +
'font-size: xx-large;' +
'opacity: 0.75;' +
'padding: 0.2em 0.5em 0.2em 0.5em;' +
'position: absolute;' +
'-webkit-user-select: none;' +
'-webkit-transition: opacity 180ms ease-in;' +
'-moz-user-select: none;' +
'-moz-transition: opacity 180ms ease-in;');
this.overlayNode_.addEventListener('mousedown', function(e) {
e.preventDefault();
e.stopPropagation();
}, true);
}
this.overlayNode_.style.color = "#101010";
this.overlayNode_.style.backgroundColor = "#f0f0f0";
this.overlayNode_.textContent = msg;
this.overlayNode_.style.opacity = '0.75';
if (!this.overlayNode_.parentNode)
this.element.appendChild(this.overlayNode_);
var divSize = this.element.getBoundingClientRect();
var overlaySize = this.overlayNode_.getBoundingClientRect();
this.overlayNode_.style.top =
(divSize.height - overlaySize.height) / 2 + 'px';
this.overlayNode_.style.left = (divSize.width - overlaySize.width) / 2 + 'px';
var self = this;
if (this.overlayTimeout_)
clearTimeout(this.overlayTimeout_);
if (timeout === null)
return;
this.overlayTimeout_ = setTimeout(function() {
self.overlayNode_.style.opacity = '0';
self.overlayTimeout_ = setTimeout(function() {
if (self.overlayNode_.parentNode)
self.overlayNode_.parentNode.removeChild(self.overlayNode_);
self.overlayTimeout_ = null;
self.overlayNode_.style.opacity = '0.75';
}, 200);
}, timeout || 1500);
};