gommand/static/start-interactive.js

98 lines
3.1 KiB
JavaScript
Raw Normal View History

2025-02-11 15:11:22 +01:00
document.addEventListener("DOMContentLoaded", function () {
const input = document.getElementById("command-input");
2025-02-12 17:22:59 +01:00
// We assume your normal terminal UI is in the element with id "terminal".
const normalTerminal = document.getElementById("terminal");
2025-02-11 15:11:22 +01:00
let interactiveWS = null;
let interactiveMode = false;
const ansi_up = new AnsiUp;
2025-02-12 17:22:59 +01:00
// Listen for the "start-interactive" command in normal mode.
2025-02-11 15:11:22 +01:00
input.addEventListener("keydown", function (event) {
if (!interactiveMode && event.key === "Enter") {
const command = input.value.trim();
if (command === "start-interactive") {
startInteractiveSession();
input.value = "";
event.preventDefault();
return;
}
2025-02-12 17:22:59 +01:00
// Otherwise, your normal HTTP submission…
2025-02-11 15:11:22 +01:00
}
});
function startInteractiveSession() {
2025-02-12 17:22:59 +01:00
// Hide the normal terminal and input.
normalTerminal.style.display = "none";
input.style.display = "none";
// Create a new container for xterm.js.
const xtermContainer = document.createElement("div");
xtermContainer.id = "xterm-container";
xtermContainer.style.width = "100%";
xtermContainer.style.height = "100vh";
// Optionally set additional styling (e.g. background color).
document.body.appendChild(xtermContainer);
2025-02-11 15:11:22 +01:00
2025-02-12 17:22:59 +01:00
// Initialize xterm.js Terminal.
const term = new Terminal({
cursorBlink: true,
scrollback: 1000,
theme: {
background: "#222",
foreground: "#eee"
}
});
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(xtermContainer);
fitAddon.fit();
term.focus();
// Establish the WebSocket connection.
interactiveWS = new WebSocket("ws://" + location.host + "/terminal");
2025-02-11 15:11:22 +01:00
interactiveWS.binaryType = "arraybuffer";
interactiveWS.onmessage = function (event) {
2025-02-12 17:22:59 +01:00
const text = new TextDecoder("utf-8").decode(event.data);
term.write(text);
2025-02-11 15:11:22 +01:00
};
interactiveWS.onclose = function () {
interactiveMode = false;
2025-02-12 17:22:59 +01:00
term.write("\r\n--- Interactive session ended ---\r\n");
// Remove the xterm container.
if (xtermContainer.parentNode) {
xtermContainer.parentNode.removeChild(xtermContainer);
}
// Restore the normal terminal UI.
normalTerminal.style.display = "block";
2025-02-11 15:11:22 +01:00
input.style.display = "block";
input.focus();
};
interactiveWS.onerror = function (err) {
2025-02-12 17:22:59 +01:00
term.write("\r\n--- Error in interactive session ---\r\n");
2025-02-11 15:11:22 +01:00
console.error("Interactive WS error:", err);
interactiveMode = false;
2025-02-12 17:22:59 +01:00
if (xtermContainer.parentNode) {
xtermContainer.parentNode.removeChild(xtermContainer);
}
normalTerminal.style.display = "block";
2025-02-11 15:11:22 +01:00
input.style.display = "block";
};
2025-02-12 17:22:59 +01:00
// When the user types in xterm, send the data to the server.
term.onData(function (data) {
// If the user presses Ctrl+D (ASCII 4), exit the session.
if (data === "\x04") {
term.write("\r\n--- Exiting interactive session ---\r\n");
interactiveWS.close();
2025-02-11 15:11:22 +01:00
} else {
2025-02-12 17:22:59 +01:00
interactiveWS.send(data);
2025-02-11 15:11:22 +01:00
}
2025-02-12 17:22:59 +01:00
});
2025-02-11 15:11:22 +01:00
2025-02-12 17:22:59 +01:00
interactiveMode = true;
2025-02-11 15:11:22 +01:00
}
});