Prevent g c from leaking into global shortcuts

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
dotta 2026-04-08 11:12:01 -05:00
parent ba5cb34bed
commit e15b5412ec
3 changed files with 64 additions and 0 deletions

View file

@ -0,0 +1,58 @@
// @vitest-environment jsdom
import { act } from "react";
import { createRoot } from "react-dom/client";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useKeyboardShortcuts } from "./useKeyboardShortcuts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).IS_REACT_ACT_ENVIRONMENT = true;
function TestHarness({
onNewIssue,
}: {
onNewIssue: () => void;
}) {
useKeyboardShortcuts({
enabled: true,
onNewIssue,
});
return <div>keyboard shortcuts test</div>;
}
describe("useKeyboardShortcuts", () => {
let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
container.remove();
});
it("ignores events already claimed by another handler", () => {
const root = createRoot(container);
const onNewIssue = vi.fn();
act(() => {
root.render(<TestHarness onNewIssue={onNewIssue} />);
});
const event = new KeyboardEvent("keydown", {
key: "c",
bubbles: true,
cancelable: true,
});
event.preventDefault();
document.dispatchEvent(event);
expect(onNewIssue).not.toHaveBeenCalled();
act(() => {
root.unmount();
});
});
});

View file

@ -20,6 +20,10 @@ export function useKeyboardShortcuts({
if (!enabled) return;
function handleKeyDown(e: KeyboardEvent) {
if (e.defaultPrevented) {
return;
}
// Don't fire shortcuts when typing in inputs
if (isKeyboardShortcutTextInputTarget(e.target)) {
return;

View file

@ -1332,11 +1332,13 @@ export function IssueDetail() {
disarm();
if (action === "navigate_inbox") {
event.preventDefault();
event.stopPropagation();
navigate(sourceBreadcrumb.href.startsWith("/inbox") ? sourceBreadcrumb.href : "/inbox");
return;
}
if (action === "focus_comment") {
event.preventDefault();
event.stopPropagation();
setDetailTab("chat");
setPendingCommentComposerFocusKey((current) => current + 1);
}