interaction.ts

1.8 KB · raw

1import type { DetectedField } from "./detect";2import { isAnyCredentialForm } from "./detect";34export interface AutofillInteractionTargets {5  usernameEl: HTMLInputElement | null;6  passwordEl: HTMLInputElement | null;7  /** Separate email field, present only when the form has both a username and a distinct email field. */8  emailEl: HTMLInputElement | null;9  shouldOpen: boolean;10}1112/**13 * Explicit icon clicks should still work when passive heuristics are too14 * cautious. Prefer the real detected fields when present, but allow the click15 * path to open Peach even if the current page only exposes a partial form.16 */17export function resolveAutofillInteractionTargets(18  anchorField: HTMLInputElement,19  fields: DetectedField[],20  explicitSummon = false21): AutofillInteractionTargets {22  const usernameField = fields.find((f) => f.type === "username");23  const emailField = fields.find((f) => f.type === "email");24  const pwField = fields.find((f) => f.type === "password");25  const anchorType = anchorField.type.toLowerCase();26  const fallbackType = anchorType === "password" ? "password" : "username";2728  // When both a username and a dedicated email field exist, track them separately.29  // When only an email field exists (email-first login / email-as-identifier), treat it30  // as usernameEl so callers fill it with entry.username; emailEl stays null.31  const hasDistinctUsername = !!usernameField;32  const identityEl = usernameField?.el ?? emailField?.el ?? null;3334  return {35    usernameEl: identityEl ?? (explicitSummon && fallbackType === "username" ? anchorField : null),36    passwordEl: pwField?.el ?? (explicitSummon && fallbackType === "password" ? anchorField : null),37    emailEl: hasDistinctUsername ? (emailField?.el ?? null) : null,38    shouldOpen: explicitSummon || isAnyCredentialForm(fields),39  };40}