Skip to content

Fix hotkeys triggering text search on firefox#3620

Open
akaltar wants to merge 2 commits intoopenfrontio:mainfrom
akaltar:m/fix-firefox-hotkeys
Open

Fix hotkeys triggering text search on firefox#3620
akaltar wants to merge 2 commits intoopenfrontio:mainfrom
akaltar:m/fix-firefox-hotkeys

Conversation

@akaltar
Copy link
Copy Markdown

@akaltar akaltar commented Apr 9, 2026

Description:

On firefox desktop, typing anything starts searching on the page by default , similar to ctrl + F shortcut on other browsers.
This causes the active keys to get stuck and most of the hotkeys to not work.
Here is how that looked like when pressing "a" to scroll left:
image

To fix I've added:

  • Platform detection for firefox
  • Conditionally calling preventDefault on text-like keydowns that are commonly used in the game, and only on firefox
  • Test that verify firefox detection
  • Test that verifies preventDefault being called at the correct times
  • Manually verified that browser zoom and shortcuts like opening the browser developer tools aren't affected

Maybe a more ideal fix could be to check if there is a bound key that matches the current key pressed, and only preventDefault then. I'm open to implementing any suggested approach if a different one is preferred.

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory
  • I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced

Please put your Discord username so you can be contacted if a bug or regression is found:

Discord username: akaltar
But I'm more likely to respond quickly to being tagged on github

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 9, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

Walkthrough

Adds Firefox detection to Platform and uses it in InputHandler to call preventDefault() for plain text/number key presses on Firefox, preventing the browser's page text search. Tests updated to cover Platform.isFirefox and the new InputHandler behavior.

Changes

Cohort / File(s) Summary
Platform Detection
src/client/Platform.ts, tests/client/Platform.test.ts
Add exported Platform.isFirefox: boolean (detects /Firefox/i from navigator.userAgent) and tests that assert Firefox UA yields true and unknown platform yields false.
Input Handler Firefox Prevention
src/client/InputHandler.ts, tests/InputHandler.test.ts
Introduce TextKeyCodeRE pattern and Firefox-specific branch: when Platform.isFirefox and a text/number key is pressed with no modifiers, call e.preventDefault(). Tests added to verify defaultPrevented behavior for plain keys vs. modifier-involved keys.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🦊 Firefox hears the typing beat,
A regex guards the text-key fleet,
Platform flags the browser true,
preventDefault() comes to the rescue —
Quiet search, and code moves neat.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly matches the main change: adding Firefox-specific prevention of text search triggered by hotkeys.
Description check ✅ Passed The description thoroughly explains the Firefox text search problem, the solution approach, test coverage, and manual verification, all matching the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/client/Platform.ts`:
- Line 53: The module reads navigator.userAgent into the const isFirefox at
top-level which can throw in non-browser environments; change the initialization
to guard against missing browser globals by using the existing isBrowser check
(or typeof navigator !== 'undefined') before testing the userAgent, e.g. compute
isFirefox as a boolean expression that short-circuits when not in a browser (use
isBrowser && /Firefox/i.test(navigator.userAgent) or similar) so module
initialization never accesses navigator in non-browser contexts.

In `@tests/InputHandler.test.ts`:
- Around line 755-756: The test is incorrectly using vi.spyOn(Platform,
"isFirefox", "get") on a plain data property; replace the spy call with direct
property assignment or a temporary defineProperty override on Platform.isFirefox
in the test (e.g., save the original value, set Platform.isFirefox = true for
the test, then restore the original in afterEach) so the mock does not throw at
runtime—target the Platform.isFirefox symbol in InputHandler.test.ts and ensure
the original value is restored after the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: de351d94-7ad2-4e38-a61d-e378f5ed8ff8

📥 Commits

Reviewing files that changed from the base of the PR and between 7f7cbba and 7b885d2.

📒 Files selected for processing (4)
  • src/client/InputHandler.ts
  • src/client/Platform.ts
  • tests/InputHandler.test.ts
  • tests/client/Platform.test.ts

@github-project-automation github-project-automation bot moved this from Triage to Development in OpenFront Release Management Apr 9, 2026
@VariableVince
Copy link
Copy Markdown
Contributor

@akaltar Hi, thanks for this. I'm not a reviewer, but have you been able to check CodeRabbit's feedback? It makes valid points quite a lot

@akaltar akaltar requested a review from a team as a code owner April 12, 2026 12:15
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
tests/InputHandler.test.ts (1)

767-769: ⚠️ Potential issue | 🟡 Minor

Restore the original Platform.isFirefox value, not a hardcoded false.

At Line 768, hardcoding false can leak incorrect global state across tests. Save the previous value and restore it in teardown.

Suggested fix
 describe("preventDefault is called on firefox keybinds", () => {
+  let previousIsFirefox: boolean;
+
+  beforeAll(() => {
+    previousIsFirefox = Platform.isFirefox;
+  });
+
   beforeEach(() => {
@@
       Platform.isFirefox = true;
@@
   afterAll(() => {
-    Platform.isFirefox = false;
+    Platform.isFirefox = previousIsFirefox;
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/InputHandler.test.ts` around lines 767 - 769, The teardown currently
overwrites Platform.isFirefox with a hardcoded false; instead capture the
original value (e.g., const originalIsFirefox = Platform.isFirefox) before tests
run (in the containing describe or beforeAll) and restore that saved value in
afterAll using Platform.isFirefox = originalIsFirefox so global state is
returned to its prior value rather than always false.
🧹 Nitpick comments (1)
tests/InputHandler.test.ts (1)

744-797: Add a non-Firefox assertion for plain text keydown.

Current coverage only verifies Firefox mode. Add one test where Platform.isFirefox = false and Digit1 does not call preventDefault, so “Firefox-only” behavior is protected.

Suggested test addition
   test("should preventDefault on simple button press", () => {
@@
     expect(event.defaultPrevented).toBeTruthy();
   });

+  test("should not preventDefault on simple button press outside Firefox", () => {
+    Platform.isFirefox = false;
+    const event = new KeyboardEvent("keydown", {
+      code: "Digit1",
+      key: "1",
+      cancelable: true,
+    });
+
+    window.dispatchEvent(event);
+
+    expect(event.defaultPrevented).toBeFalsy();
+  });
+
   test("Shouldn't call preventDefault for browser shortcut like zoom", () => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/InputHandler.test.ts` around lines 744 - 797, Add a mirror test for
non-Firefox behavior: create a test that sets Platform.isFirefox = false,
initializes InputHandler (using the same setup as the Firefox tests or reusing
the existing beforeEach), dispatches a cancelable KeyboardEvent with code
"Digit1"/key "1" and then asserts event.defaultPrevented is false; ensure
Platform.isFirefox is restored/reset the same way other tests do and reuse
InputHandler/initialize from the existing test setup so the new test protects
the Firefox-only behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/InputHandler.test.ts`:
- Around line 767-769: The teardown currently overwrites Platform.isFirefox with
a hardcoded false; instead capture the original value (e.g., const
originalIsFirefox = Platform.isFirefox) before tests run (in the containing
describe or beforeAll) and restore that saved value in afterAll using
Platform.isFirefox = originalIsFirefox so global state is returned to its prior
value rather than always false.

---

Nitpick comments:
In `@tests/InputHandler.test.ts`:
- Around line 744-797: Add a mirror test for non-Firefox behavior: create a test
that sets Platform.isFirefox = false, initializes InputHandler (using the same
setup as the Firefox tests or reusing the existing beforeEach), dispatches a
cancelable KeyboardEvent with code "Digit1"/key "1" and then asserts
event.defaultPrevented is false; ensure Platform.isFirefox is restored/reset the
same way other tests do and reuse InputHandler/initialize from the existing test
setup so the new test protects the Firefox-only behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ddf79c44-92b5-4315-a8f8-57033242662a

📥 Commits

Reviewing files that changed from the base of the PR and between 7b885d2 and 40782c5.

📒 Files selected for processing (2)
  • src/client/Platform.ts
  • tests/InputHandler.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/client/Platform.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

3 participants