mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
@@ -217,9 +217,14 @@ export function TerminalInput(): React.ReactElement {
|
||||
const ref = terminalInput.current;
|
||||
if (event.ctrlKey || event.metaKey) return;
|
||||
if (event.key === KEY.C && (event.ctrlKey || event.metaKey)) return; // trying to copy
|
||||
// Don't steal focus from other input elements (e.g., prompt dialogs)
|
||||
// Don't steal focus from other input elements
|
||||
const target = event.target;
|
||||
if ((target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) && target !== ref) {
|
||||
if (
|
||||
(target instanceof HTMLInputElement ||
|
||||
target instanceof HTMLTextAreaElement ||
|
||||
(target instanceof HTMLElement && target.isContentEditable)) &&
|
||||
target !== ref
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (ref) ref.focus();
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
* Tests for the terminal's document-level keydown handler and its interaction
|
||||
* with other input elements (e.g., prompt dialogs).
|
||||
*
|
||||
* The terminal registers a document-level keydown listener that calls focus()
|
||||
* on the terminal input to redirect all keyboard input there. This test
|
||||
* verifies that the handler does NOT steal focus from other input elements
|
||||
* like the text prompt dialog.
|
||||
*
|
||||
* See: https://github.com/bitburner-official/bitburner-src/issues/924
|
||||
*/
|
||||
|
||||
describe("Terminal focus behavior", () => {
|
||||
let terminalInput: HTMLInputElement;
|
||||
let promptInput: HTMLInputElement;
|
||||
|
||||
beforeEach(() => {
|
||||
terminalInput = document.createElement("input");
|
||||
terminalInput.id = "terminal-input";
|
||||
promptInput = document.createElement("input");
|
||||
promptInput.id = "prompt-input";
|
||||
document.body.append(terminalInput, promptInput);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
terminalInput.remove();
|
||||
promptInput.remove();
|
||||
});
|
||||
|
||||
// Simulates the terminal's keydown handler with the fix applied:
|
||||
// skip focus redirect if the event target is an input/textarea that isn't the terminal
|
||||
function fixedKeyDown(event: KeyboardEvent) {
|
||||
if (event.ctrlKey || event.metaKey) return;
|
||||
const target = event.target;
|
||||
if ((target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) && target !== terminalInput) {
|
||||
return;
|
||||
}
|
||||
terminalInput.focus();
|
||||
}
|
||||
|
||||
it("should not steal focus from prompt input on keydown", () => {
|
||||
document.addEventListener("keydown", fixedKeyDown);
|
||||
|
||||
// User opens a prompt dialog and the text field gets focus
|
||||
promptInput.focus();
|
||||
expect(document.activeElement).toBe(promptInput);
|
||||
|
||||
// User types in the prompt — focus should stay there
|
||||
promptInput.dispatchEvent(new KeyboardEvent("keydown", { key: "a", bubbles: true }));
|
||||
expect(document.activeElement).toBe(promptInput);
|
||||
|
||||
// Multiple keystrokes should all stay in the prompt
|
||||
promptInput.dispatchEvent(new KeyboardEvent("keydown", { key: "b", bubbles: true }));
|
||||
promptInput.dispatchEvent(new KeyboardEvent("keydown", { key: "c", bubbles: true }));
|
||||
expect(document.activeElement).toBe(promptInput);
|
||||
|
||||
document.removeEventListener("keydown", fixedKeyDown);
|
||||
});
|
||||
|
||||
it("should still redirect focus to terminal when typing on the page background", () => {
|
||||
document.addEventListener("keydown", fixedKeyDown);
|
||||
|
||||
// No input has focus — user clicks on empty page area, then types
|
||||
document.body.focus();
|
||||
expect(document.activeElement).toBe(document.body);
|
||||
|
||||
// Keydown from body should redirect to terminal
|
||||
document.body.dispatchEvent(new KeyboardEvent("keydown", { key: "a", bubbles: true }));
|
||||
expect(document.activeElement).toBe(terminalInput);
|
||||
|
||||
document.removeEventListener("keydown", fixedKeyDown);
|
||||
});
|
||||
|
||||
it("should still redirect focus when the terminal input itself has focus", () => {
|
||||
document.addEventListener("keydown", fixedKeyDown);
|
||||
|
||||
terminalInput.focus();
|
||||
terminalInput.dispatchEvent(new KeyboardEvent("keydown", { key: "a", bubbles: true }));
|
||||
expect(document.activeElement).toBe(terminalInput);
|
||||
|
||||
document.removeEventListener("keydown", fixedKeyDown);
|
||||
});
|
||||
|
||||
it("should not steal focus from textarea elements either", () => {
|
||||
const textarea = document.createElement("textarea");
|
||||
document.body.appendChild(textarea);
|
||||
document.addEventListener("keydown", fixedKeyDown);
|
||||
|
||||
textarea.focus();
|
||||
textarea.dispatchEvent(new KeyboardEvent("keydown", { key: "x", bubbles: true }));
|
||||
expect(document.activeElement).toBe(textarea);
|
||||
|
||||
document.removeEventListener("keydown", fixedKeyDown);
|
||||
textarea.remove();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user