mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 11:46:49 +00:00
@xterm/xterm 6.0.0 and @xterm/addon-fit 0.11.0 replace xterm 3.6.0; the page reads typed and pasted input with onData, and no longer writes every key and all terminal output to the browser console. The unused fullscreen addon goes.
137 lines
4.5 KiB
HTML
137 lines
4.5 KiB
HTML
{% extends "console-base.html" %}
|
|
{% load i18n %}
|
|
{% load static %}
|
|
|
|
{% block head %}
|
|
<title>WebVirtCloud - XTerm</title>
|
|
<link rel="stylesheet" href="{% static 'css/xterm.css' %}"/>
|
|
<script src="{% static 'js/xterm/xterm.js' %}"></script>
|
|
<script src="{% static 'js/xterm/addon-fit.js' %}"></script>
|
|
|
|
<script src="{% static 'js/socket.io.js' %}"></script>
|
|
|
|
{% endblock %}
|
|
{% block content %}
|
|
<div style="background: white; padding-bottom: 5px;">
|
|
<span style="font-size: small;">Status: <span style="font-size: small;" id="status">connecting...</span></span>
|
|
<button id="button" type="button" onclick="myFunction();">Connect</button>
|
|
</div>
|
|
|
|
<div style="width: 100%; height:100%;" id="terminal"></div>
|
|
<script crossorigin="anonymous">
|
|
let host = readQueryVariable('host', '{{ socketio_host|escapejs }}');
|
|
let port = readQueryVariable('port', '{{ socketio_port|escapejs }}');
|
|
let path = readQueryVariable('path', '{{ socketio_path|escapejs }}');
|
|
|
|
|
|
// Build the websocket URL used to connect
|
|
let url;
|
|
if (window.location.protocol === "https:") {
|
|
url = 'wss';
|
|
} else {
|
|
url = 'ws';
|
|
}
|
|
url += '://' + host;
|
|
if (port) {
|
|
url += ':' + port;
|
|
}
|
|
|
|
var socket = io.connect(url, {transports: ["websocket", "polling"]});
|
|
|
|
const status = document.getElementById("status");
|
|
const button = document.getElementById("button");
|
|
|
|
var term = new Terminal({
|
|
cursorBlink: true,
|
|
});
|
|
var fitAddon = new FitAddon.FitAddon();
|
|
term.loadAddon(fitAddon);
|
|
|
|
term.open(document.getElementById('terminal'));
|
|
|
|
// typed and pasted input
|
|
term.onData((data) => {
|
|
socket.emit("pty_input", {"input": data})
|
|
});
|
|
|
|
socket.on("pty_output", function(output){
|
|
term.write(output["output"])
|
|
})
|
|
|
|
socket.on("connect", () => {
|
|
status.innerHTML = '<span style="background-color: lightgreen;">connected</span>'
|
|
button.innerHTML = 'Disconnect'
|
|
})
|
|
|
|
socket.on("disconnect", () => {
|
|
status.innerHTML = '<span style="background-color: #ff8383;">disconnected</span>'
|
|
button.innerHTML = 'Connect'
|
|
})
|
|
|
|
function myFunction(){
|
|
if (button.innerHTML =='Connect'){
|
|
location.reload();
|
|
}
|
|
|
|
else if (button.innerHTML == "Disconnect"){
|
|
socket.emit("disconnect_request")
|
|
}
|
|
}
|
|
|
|
function resize(){
|
|
fitAddon.fit()
|
|
socket.emit("resize", {"cols": term.cols, "rows": term.rows})
|
|
}
|
|
|
|
// This function extracts the value of one variable from the
|
|
// query string. If the variable isn't defined in the URL
|
|
// it returns the default value instead.
|
|
function readQueryVariable(name, defaultValue) {
|
|
// A URL with a query parameter can look like this:
|
|
// https://www.example.com?myqueryparam=myvalue
|
|
//
|
|
// Note that we use location.href instead of location.search
|
|
// because Firefox < 53 has a bug w.r.t location.search
|
|
const re = new RegExp('.*[?&]' + name + '=([^&#]*)'),
|
|
match = document.location.href.match(re);
|
|
|
|
if (match) {
|
|
// We have to decode the URL since want the cleartext value
|
|
return decodeURIComponent(match[1]);
|
|
}
|
|
|
|
return defaultValue;
|
|
}
|
|
|
|
function bindTerminalKey(id, str) {
|
|
const el = document.getElementById(id);
|
|
if (el) {
|
|
el.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
socket.emit("pty_input", {"input": str});
|
|
});
|
|
}
|
|
}
|
|
bindTerminalKey('ctrlc', '\x03');
|
|
bindTerminalKey('ctrld', '\x04');
|
|
bindTerminalKey('ctrlz', '\x1a');
|
|
bindTerminalKey('ctrlbackslash', '\x1c');
|
|
bindTerminalKey('sendtab', '\t');
|
|
bindTerminalKey('sendesc', '\x1b');
|
|
|
|
const fsBtn = document.getElementById('fullscreen_button');
|
|
if (fsBtn) {
|
|
fsBtn.addEventListener('click', (e) => {
|
|
e.preventDefault();
|
|
if (document.fullscreenElement) {
|
|
document.exitFullscreen().catch(() => {});
|
|
} else {
|
|
document.documentElement.requestFullscreen().catch(() => {});
|
|
}
|
|
});
|
|
}
|
|
|
|
window.onresize = resize;
|
|
window.onload = resize;
|
|
</script>
|
|
{% endblock %}
|