[PM-8833] Refining mouse interactions with filled fields

This commit is contained in:
Cesar Gonzalez 2024-09-23 09:24:58 -05:00
parent 97a9edfda6
commit 3fe78fdead
No known key found for this signature in database
GPG Key ID: 3381A5457F8CCECF
2 changed files with 27 additions and 12 deletions

View File

@ -31,6 +31,7 @@ import AutofillField from "../models/autofill-field";
import AutofillPageDetails from "../models/autofill-page-details"; import AutofillPageDetails from "../models/autofill-page-details";
import { ElementWithOpId, FillableFormFieldElement, FormFieldElement } from "../types"; import { ElementWithOpId, FillableFormFieldElement, FormFieldElement } from "../types";
import { import {
debounce,
elementIsFillableFormField, elementIsFillableFormField,
elementIsSelectElement, elementIsSelectElement,
getAttributeBoolean, getAttributeBoolean,
@ -670,9 +671,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
* is currently focused. * is currently focused.
*/ */
private handleFormFieldBlurEvent = () => { private handleFormFieldBlurEvent = () => {
void this.sendExtensionMessage("updateIsFieldCurrentlyFocused", { void this.updateIsFieldCurrentlyFocused(false);
isFieldCurrentlyFocused: false,
});
void this.sendExtensionMessage("checkAutofillInlineMenuFocused"); void this.sendExtensionMessage("checkAutofillInlineMenuFocused");
}; };
@ -733,7 +732,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
*/ */
private handleFormFieldInputEvent = (formFieldElement: ElementWithOpId<FormFieldElement>) => { private handleFormFieldInputEvent = (formFieldElement: ElementWithOpId<FormFieldElement>) => {
return this.useEventHandlersMemo( return this.useEventHandlersMemo(
() => this.triggerFormFieldInput(formFieldElement), debounce(() => this.triggerFormFieldInput(formFieldElement), 100, true),
this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.INPUT), this.getFormFieldHandlerMemoIndex(formFieldElement, EVENTS.INPUT),
); );
}; };
@ -755,7 +754,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
return; return;
} }
if (await this.hideInlineMenuListOnFilledField(formFieldElement)) { if (formFieldElement?.value) {
void this.sendExtensionMessage("closeAutofillInlineMenu", { void this.sendExtensionMessage("closeAutofillInlineMenu", {
overlayElement: AutofillOverlayElement.List, overlayElement: AutofillOverlayElement.List,
forceCloseInlineMenu: true, forceCloseInlineMenu: true,
@ -911,9 +910,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
return; return;
} }
await this.sendExtensionMessage("updateIsFieldCurrentlyFocused", { await this.updateIsFieldCurrentlyFocused(true);
isFieldCurrentlyFocused: true,
});
const initiallyFocusedField = this.mostRecentlyFocusedField; const initiallyFocusedField = this.mostRecentlyFocusedField;
await this.updateMostRecentlyFocusedField(formFieldElement); await this.updateMostRecentlyFocusedField(formFieldElement);
@ -935,9 +932,13 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
return; return;
} }
void this.sendExtensionMessage("openAutofillInlineMenu"); await this.sendExtensionMessage("openAutofillInlineMenu");
} }
private updateIsFieldCurrentlyFocused = async (isFieldCurrentlyFocused: boolean) => {
await this.sendExtensionMessage("updateIsFieldCurrentlyFocused", { isFieldCurrentlyFocused });
};
/** /**
* Validates whether the user is currently authenticated. * Validates whether the user is currently authenticated.
*/ */

View File

@ -378,12 +378,26 @@ export function throttle(callback: (_args: any) => any, limit: number) {
* *
* @param callback - The callback function to debounce. * @param callback - The callback function to debounce.
* @param delay - The time in milliseconds to debounce the callback. * @param delay - The time in milliseconds to debounce the callback.
* @param immediate - Determines whether the callback should run immediately.
*/ */
export function debounce(callback: (_args: any) => any, delay: number) { export function debounce(callback: (_args: any) => any, delay: number, immediate?: boolean) {
let timeout: NodeJS.Timeout; let timeout: NodeJS.Timeout;
return function (...args: unknown[]) { return function (...args: unknown[]) {
globalThis.clearTimeout(timeout); const callImmediately = !!immediate && !timeout;
timeout = globalThis.setTimeout(() => callback.apply(this, args), delay);
if (timeout) {
globalThis.clearTimeout(timeout);
}
timeout = globalThis.setTimeout(() => {
timeout = null;
if (!callImmediately) {
callback.apply(this, args);
}
}, delay);
if (callImmediately) {
callback.apply(this, args);
}
}; };
} }