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
|
|
|
}
|
|
|
|
});
|