Files
ttyd/html/js/app.js
2017-11-25 22:53:44 +08:00

117 lines
4.2 KiB
JavaScript

(function() {
var terminalContainer = document.getElementById('terminal-container'),
httpsEnabled = window.location.protocol === "https:",
url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws',
authToken = (typeof tty_auth_token !== 'undefined') ? tty_auth_token : null,
protocols = ["tty"],
autoReconnect = -1,
term, pingTimer, wsError;
var openWs = function() {
var ws = new WebSocket(url, protocols),
textDecoder = new TextDecoder(),
textEncoder = new TextEncoder();
var unloadCallback = function(event) {
var message = 'Close terminal? this will also terminate the command.';
(event || window.event).returnValue = message;
return message;
};
var sendMessage = function (msg) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(textEncoder.encode(msg));
}
};
var sendPing = function() {
sendMessage("1");
};
ws.binaryType = 'arraybuffer';
ws.onopen = function() {
console.log("Websocket connection opened");
wsError = false;
sendMessage(JSON.stringify({AuthToken: authToken}));
pingTimer = setInterval(sendPing, 30 * 1000);
if (typeof term !== 'undefined') {
term.destroy();
}
term = new Terminal();
term.on('resize', function(size) {
sendMessage("2" + JSON.stringify({columns: size.cols, rows: size.rows}));
setTimeout(function() {
term.showOverlay(size.cols + 'x' + size.rows);
}, 500);
});
term.on("data", function(data) {
sendMessage("0" + data);
});
term.on('open', function() {
// https://stackoverflow.com/a/27923937/1727928
window.addEventListener('resize', function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function () {
term.fit();
}, 250);
});
window.addEventListener('beforeunload', unloadCallback);
term.fit();
});
while (terminalContainer.firstChild) {
terminalContainer.removeChild(terminalContainer.firstChild);
}
term.open(terminalContainer, true);
};
ws.onmessage = function(event) {
var cmd = String.fromCharCode(new DataView(event.data).getUint8()),
data = textDecoder.decode(event.data.slice(1));
switch(cmd) {
case '0':
term.write(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) {
console.log("Websocket connection closed with code: " + event.code);
if (term) {
term.off('data');
term.off('resize');
if (!wsError) {
term.showOverlay("Connection Closed", null);
}
}
window.removeEventListener('beforeunload', unloadCallback);
clearInterval(pingTimer);
// 1000: CLOSE_NORMAL
if (event.code !== 1000 && autoReconnect > 0) {
setTimeout(openWs, autoReconnect * 1000);
}
};
};
openWs();
})();