AT Mot — a bilingual (EN/FR) daily word game native to the AT Protocol.
0

Configure Feed

Select the types of activity you want to include in your feed.

Ignore keystrokes from editable fields so sign-in typing doesn't reach the board

Add isEditableTarget() and guard the global keydown handler with it, plus a test.

+39
+11
src/ui/dom.ts
··· 58 58 export function clear(container: HTMLElement): void { 59 59 container.replaceChildren(); 60 60 } 61 + 62 + /** 63 + * True when an event originated from an editable element (text input, textarea, 64 + * or contenteditable). Used to ignore global keystrokes while the user is typing 65 + * into a field such as the sign-in form, so they don't leak into the game board. 66 + */ 67 + export function isEditableTarget(target: EventTarget | null): boolean { 68 + if (!(target instanceof HTMLElement)) return false; 69 + const tag = target.tagName; 70 + return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable; 71 + }
+28
tests/dom.test.ts
··· 1 + // @vitest-environment happy-dom 2 + import { describe, expect, it } from 'vitest'; 3 + import { isEditableTarget } from '../src/ui/dom.js'; 4 + 5 + describe('isEditableTarget', () => { 6 + it('is true for an <input> (e.g. the sign-in field)', () => { 7 + expect(isEditableTarget(document.createElement('input'))).toBe(true); 8 + }); 9 + 10 + it('is true for a <textarea>', () => { 11 + expect(isEditableTarget(document.createElement('textarea'))).toBe(true); 12 + }); 13 + 14 + it('is true for a contenteditable element', () => { 15 + const div = document.createElement('div'); 16 + div.setAttribute('contenteditable', 'true'); 17 + expect(isEditableTarget(div)).toBe(true); 18 + }); 19 + 20 + it('is false for the on-screen keyboard buttons and other elements', () => { 21 + expect(isEditableTarget(document.createElement('button'))).toBe(false); 22 + expect(isEditableTarget(document.createElement('div'))).toBe(false); 23 + }); 24 + 25 + it('is false for a null target', () => { 26 + expect(isEditableTarget(null)).toBe(false); 27 + }); 28 + });