spug/spug_web/public/xterm/main.js

150 lines
3.3 KiB
JavaScript

let style = {};
function get_cell_size(term) {
style.width = term._core._renderService._renderer.dimensions.actualCellWidth;
style.height = term._core._renderService._renderer.dimensions.actualCellHeight;
}
function current_geometry(term) {
if (!style.width || !style.height) {
get_cell_size(term);
}
const cols = parseInt(window.innerWidth / style.width, 10) - 1;
const rows = parseInt(window.innerHeight / style.height, 10);
return {'cols': cols, 'rows': rows};
}
function resize_terminal(term) {
const geometry = current_geometry(term);
term.on_resize(geometry.cols, geometry.rows);
}
function read_as_text_with_decoder(file, callback, decoder) {
let reader = new window.FileReader();
if (decoder === undefined) {
decoder = new window.TextDecoder('utf-8', {'fatal': true});
}
reader.onload = function () {
let text;
try {
text = decoder.decode(reader.result);
} catch (TypeError) {
console.log('Decoding error happened.');
} finally {
if (callback) {
callback(text);
}
}
};
reader.onerror = function (e) {
console.error(e);
};
reader.readAsArrayBuffer(file);
}
function read_as_text_with_encoding(file, callback, encoding) {
let reader = new window.FileReader();
if (encoding === undefined) {
encoding = 'utf-8';
}
reader.onload = function () {
if (callback) {
callback(reader.result);
}
};
reader.onerror = function (e) {
console.error(e);
};
reader.readAsText(file, encoding);
}
function read_file_as_text(file, callback, decoder) {
if (!window.TextDecoder) {
read_as_text_with_encoding(file, callback, decoder);
} else {
read_as_text_with_decoder(file, callback, decoder);
}
}
function run(id, token) {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const sock = new window.WebSocket(`${protocol}//${window.location.host}/api/ws/ssh/${token}/${id}/`),
encoding = 'utf-8',
decoder = window.TextDecoder ? new window.TextDecoder(encoding) : encoding,
terminal = document.getElementById('terminal'),
term = new window.Terminal({
cursorBlink: true,
theme: {
background: 'black'
}
});
term.fitAddon = new window.FitAddon.FitAddon();
term.loadAddon(term.fitAddon);
function term_write(text) {
if (term) {
term.write(text);
if (!term.resized) {
resize_terminal(term);
term.resized = true;
}
}
}
term.on_resize = function (cols, rows) {
if (cols !== this.cols || rows !== this.rows) {
this.resize(cols, rows);
sock.send(JSON.stringify({'resize': [cols, rows]}));
}
};
term.onData(function (data) {
sock.send(JSON.stringify({'data': data}));
});
sock.onopen = function () {
term.open(terminal);
term.fitAddon.fit();
term.focus();
};
sock.onmessage = function (msg) {
read_file_as_text(msg.data, term_write, decoder);
};
sock.onerror = function (e) {
console.error(e);
};
sock.onclose = function (e) {
if (e.code === 3333) {
window.location.href = "about:blank";
window.close()
} else {
setTimeout(() => term_write('\r\nConnection is closed.\r\n'), 200)
}
};
window.onresize = function () {
if (term) {
resize_terminal(term);
}
};
}