import type { DetectedField } from "./detect"; import { isAnyCredentialForm } from "./detect"; export interface AutofillInteractionTargets { usernameEl: HTMLInputElement | null; passwordEl: HTMLInputElement | null; /** Separate email field, present only when the form has both a username and a distinct email field. */ emailEl: HTMLInputElement | null; shouldOpen: boolean; } /** * Explicit icon clicks should still work when passive heuristics are too * cautious. Prefer the real detected fields when present, but allow the click * path to open Peach even if the current page only exposes a partial form. */ export function resolveAutofillInteractionTargets( anchorField: HTMLInputElement, fields: DetectedField[], explicitSummon = false ): AutofillInteractionTargets { const usernameField = fields.find((f) => f.type === "username"); const emailField = fields.find((f) => f.type === "email"); const pwField = fields.find((f) => f.type === "password"); const anchorType = anchorField.type.toLowerCase(); const fallbackType = anchorType === "password" ? "password" : "username"; // When both a username and a dedicated email field exist, track them separately. // When only an email field exists (email-first login / email-as-identifier), treat it // as usernameEl so callers fill it with entry.username; emailEl stays null. const hasDistinctUsername = !!usernameField; const identityEl = usernameField?.el ?? emailField?.el ?? null; return { usernameEl: identityEl ?? (explicitSummon && fallbackType === "username" ? anchorField : null), passwordEl: pwField?.el ?? (explicitSummon && fallbackType === "password" ? anchorField : null), emailEl: hasDistinctUsername ? (emailField?.el ?? null) : null, shouldOpen: explicitSummon || isAnyCredentialForm(fields), }; }