in src/focus/is-for-form.ts [7:74]
export function isForForm(direction: Button, selected: HTMLElement | null): boolean {
if (!selected) {
return false;
}
// Always allow the browser to handle enter key presses in a form or text area.
if (direction === Button.Submit) {
let parent: HTMLElement | null = selected;
while (parent) {
if (
parent.tagName === 'FORM' ||
parent.tagName === 'TEXTAREA' ||
(parent.tagName === 'INPUT' &&
(parent as HTMLInputElement).type !== 'button' &&
(parent as HTMLInputElement).type !== 'checkbox' &&
(parent as HTMLInputElement).type !== 'radio')
) {
return true;
}
parent = parent.parentElement;
}
return false;
}
// Okay, not a submission? Well, if we aren't inside a text input, go ahead
// and let arcade-machine try to deal with the output.
const tag = selected.tagName;
if (tag !== 'INPUT' && tag !== 'TEXTAREA') {
return false;
}
// We'll say that up/down has no effect.
if (direction === Button.Down || direction === Button.Up) {
return false;
}
// Deal with the output ourselves, allowing arcade-machine to handle it only
// if the key press would not have any effect in the context of the input.
const input = selected as HTMLInputElement | HTMLTextAreaElement;
const { type } = input;
if (
type !== 'text' &&
type !== 'search' &&
type !== 'url' &&
type !== 'tel' &&
type !== 'password' &&
type !== 'textarea'
) {
return false;
}
const cursor = input.selectionStart;
if (cursor !== input.selectionEnd) {
// key input on any range selection will be effectual.
return true;
}
if (cursor === null) {
return false;
}
return (
(cursor > 0 && direction === Button.Left) ||
(cursor > 0 && direction === Button.Back) ||
(cursor < input.value.length && direction === Button.Right)
);
}