Skip to content

Commit

Permalink
[PM-5189] Working through content script port improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
Cesar Gonzalez committed Jun 19, 2024
1 parent 8a48e57 commit f389263
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,7 @@ export type OverlayBackgroundExtensionMessageHandlers = {
updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void;
checkIsFieldCurrentlyFilling: () => boolean;
getAutofillInlineMenuVisibility: () => void;
closeAutofillInlineMenu: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
checkAutofillInlineMenuFocused: () => void;
focusAutofillInlineMenuList: () => void;

updateAutofillInlineMenuPosition: ({
message,
sender,
Expand Down Expand Up @@ -143,10 +141,14 @@ export type OverlayContentScriptPortMessageHandlers = {
updateFocusedFieldData: ({ message, port }: PortOnMessageHandlerParams) => void;
updateIsFieldCurrentlyFocused: ({ message }: PortMessageParam) => void;
openAutofillInlineMenu: () => void;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
checkAutofillInlineMenuFocused: () => void;
focusAutofillInlineMenuList: () => void;
};

export type InlineMenuButtonPortMessageHandlers = {
[key: string]: CallableFunction;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void;
autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void;
autofillInlineMenuBlurred: () => void;
Expand All @@ -156,6 +158,7 @@ export type InlineMenuButtonPortMessageHandlers = {

export type InlineMenuListPortMessageHandlers = {
[key: string]: CallableFunction;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
checkAutofillInlineMenuButtonFocused: () => void;
autofillInlineMenuBlurred: () => void;
unlockVault: ({ port }: PortConnectionParam) => void;
Expand Down
9 changes: 6 additions & 3 deletions apps/browser/src/autofill/background/overlay.background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateIsFieldCurrentlyFilling: ({ message }) => this.updateIsFieldCurrentlyFilling(message),
checkIsFieldCurrentlyFilling: () => this.checkIsFieldCurrentlyFilling(),
getAutofillInlineMenuVisibility: () => this.getInlineMenuVisibility(),
closeAutofillInlineMenu: ({ message, sender }) => this.closeInlineMenu(sender, message),
checkAutofillInlineMenuFocused: () => this.checkInlineMenuFocused(),
focusAutofillInlineMenuList: () => this.focusInlineMenuList(),

updateAutofillInlineMenuPosition: ({ message, sender }) =>
this.updateInlineMenuPosition(message, sender),
toggleAutofillInlineMenuHidden: ({ message, sender }) =>
Expand All @@ -110,8 +108,12 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateFocusedFieldData: ({ message, port }) => this.setFocusedFieldData(message, port),
updateIsFieldCurrentlyFocused: ({ message }) => this.updateIsFieldCurrentlyFocused(message),
openAutofillInlineMenu: () => this.openInlineMenu(false),
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
checkAutofillInlineMenuFocused: () => this.checkInlineMenuFocused(),
focusAutofillInlineMenuList: () => this.focusInlineMenuList(),
};
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
triggerDelayedAutofillInlineMenuClosure: ({ port }) => this.triggerDelayedInlineMenuClosure(),
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
Expand All @@ -120,6 +122,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateAutofillInlineMenuColorScheme: () => this.updateInlineMenuButtonColorScheme(),
};
private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = {
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(),
autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(),
unlockVault: ({ port }) => this.unlockVault(port),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EVENTS } from "@bitwarden/common/autofill/constants";
import { ThemeType } from "@bitwarden/common/platform/enums";

import { sendExtensionMessage, setElementStyles } from "../../../utils";
import { setElementStyles } from "../../../utils";
import {
BackgroundPortMessageHandlers,
AutofillInlineMenuIframeService as AutofillInlineMenuIframeServiceInterface,
Expand All @@ -10,7 +10,6 @@ import {

export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframeServiceInterface {
private readonly setElementStyles = setElementStyles;
private readonly sendExtensionMessage = sendExtensionMessage;
private port: chrome.runtime.Port | null = null;
private portKey: string;
private iframeMutationObserver: MutationObserver;
Expand Down Expand Up @@ -305,7 +304,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
* mutation observer is triggered excessively.
*/
private forceCloseInlineMenu() {
void this.sendExtensionMessage("closeAutofillInlineMenu", { forceClose: true });
void this.port.postMessage({ command: "closeAutofillInlineMenu", forceClose: true });
}

private handleFadeInInlineMenuIframe() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type AutofillOverlayContentExtensionMessage = {
overlayElement?: AutofillOverlayElementType;
focusedFieldData?: FocusedFieldData;
isFieldCurrentlyFocused?: boolean;
forceCloseInlineMenu?: boolean;
} & OverlayAddNewItemMessage;

export interface AutofillOverlayContentService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -905,17 +905,6 @@ describe("AutofillOverlayContentService", () => {
});
});

it("clears the user interaction timeout", async () => {
jest.useFakeTimers();
const clearTimeoutSpy = jest.spyOn(globalThis, "clearTimeout");
autofillOverlayContentService["userInteractionEventTimeout"] = setTimeout(jest.fn(), 123);

globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
await flushPromises();

expect(clearTimeoutSpy).toHaveBeenCalledWith(expect.anything());
});

it("removes the overlay completely if the field is not focused", async () => {
jest.useFakeTimers();
jest
Expand Down Expand Up @@ -1695,14 +1684,6 @@ describe("AutofillOverlayContentService", () => {
autofillOverlayContentService["mostRecentlyFocusedField"] = autofillFieldElement;
});

it("clears the user interaction event timeout", () => {
jest.spyOn(autofillOverlayContentService as any, "clearUserInteractionEventTimeout");

autofillOverlayContentService.destroy();

expect(autofillOverlayContentService["clearUserInteractionEventTimeout"]).toHaveBeenCalled();
});

it("de-registers all global event listeners", () => {
jest.spyOn(globalThis.document, "removeEventListener");
jest.spyOn(globalThis, "removeEventListener");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,8 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
private focusableElements: FocusableElement[] = [];
private mostRecentlyFocusedField: ElementWithOpId<FormFieldElement>;
private focusedFieldData: FocusedFieldData;
private userInteractionEventTimeout: number | NodeJS.Timeout;
private recalculateSubFrameOffsetsTimeout: number | NodeJS.Timeout;
private closeInlineMenuOnRedirectTimeout: number | NodeJS.Timeout;
private focusInlineMenuListTimeout: number | NodeJS.Timeout;
private closeInlineMenuOnFilledFieldTimeout: number | NodeJS.Timeout;
private eventHandlersMemo: { [key: string]: EventListener } = {};
private readonly extensionMessageHandlers: AutofillOverlayContentExtensionMessageHandlers = {
openAutofillInlineMenu: ({ message }) => this.openInlineMenu(message),
Expand Down Expand Up @@ -207,7 +204,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.mostRecentlyFocusedField?.blur();

if (isClosingInlineMenu) {
void this.sendExtensionMessage("closeAutofillInlineMenu");
this.sendPortMessage("closeAutofillInlineMenu");
}
}

Expand Down Expand Up @@ -252,7 +249,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
if (direction === RedirectFocusDirection.Current) {
this.focusMostRecentlyFocusedField();
this.closeInlineMenuOnRedirectTimeout = globalThis.setTimeout(
() => void this.sendExtensionMessage("closeAutofillInlineMenu"),
() => this.sendPortMessage("closeAutofillInlineMenu"),
100,
);
return;
Expand Down Expand Up @@ -350,7 +347,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.sendPortMessage("updateIsFieldCurrentlyFocused", {
isFieldCurrentlyFocused: false,
});
void this.sendExtensionMessage("checkAutofillInlineMenuFocused");
this.sendPortMessage("checkAutofillInlineMenuFocused");
};

/**
Expand All @@ -364,7 +361,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
private handleFormFieldKeyupEvent = async (event: KeyboardEvent) => {
const eventCode = event.code;
if (eventCode === "Escape") {
void this.sendExtensionMessage("closeAutofillInlineMenu", {
this.sendPortMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true,
});
return;
Expand Down Expand Up @@ -394,13 +391,13 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
this.openInlineMenu({ isOpeningFullInlineMenu: true });
this.focusInlineMenuListTimeout = globalThis.setTimeout(
() => this.sendExtensionMessage("focusAutofillInlineMenuList"),
() => this.sendPortMessage("focusAutofillInlineMenuList"),
125,
);
return;
}

void this.sendExtensionMessage("focusAutofillInlineMenuList");
this.sendPortMessage("focusAutofillInlineMenuList");
}

/**
Expand Down Expand Up @@ -430,7 +427,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.storeModifiedFormElement(formFieldElement);

if (await this.hideInlineMenuListOnFilledField(formFieldElement)) {
void this.sendExtensionMessage("closeAutofillInlineMenu", {
this.sendPortMessage("closeAutofillInlineMenu", {
overlayElement: AutofillOverlayElement.List,
forceCloseInlineMenu: true,
});
Expand Down Expand Up @@ -514,13 +511,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.sendPortMessage("updateIsFieldCurrentlyFocused", {
isFieldCurrentlyFocused: true,
});
if (this.userInteractionEventTimeout) {
this.clearUserInteractionEventTimeout();
void this.toggleInlineMenuHidden(false, true);
void this.sendExtensionMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true,
});
}
const initiallyFocusedField = this.mostRecentlyFocusedField;
await this.updateMostRecentlyFocusedField(formFieldElement);

Expand All @@ -529,7 +519,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
(initiallyFocusedField !== this.mostRecentlyFocusedField &&
(await this.hideInlineMenuListOnFilledField(formFieldElement as FillableFormFieldElement)))
) {
await this.sendExtensionMessage("closeAutofillInlineMenu", {
this.sendPortMessage("closeAutofillInlineMenu", {
overlayElement: AutofillOverlayElement.List,
forceCloseInlineMenu: true,
});
Expand Down Expand Up @@ -1017,7 +1007,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
}

this.unsetMostRecentlyFocusedField();
void this.sendExtensionMessage("closeAutofillInlineMenu", {
this.sendPortMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true,
});
};
Expand Down Expand Up @@ -1135,32 +1125,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.port.postMessage({ command, ...message });
}

/**
* Clears the user interaction event timeout. This is used to ensure that
* the overlay is not repositioned while the user is interacting with it.
*/
private clearUserInteractionEventTimeout() {
if (this.userInteractionEventTimeout) {
globalThis.clearTimeout(this.userInteractionEventTimeout);
this.userInteractionEventTimeout = null;
}
}

private clearCloseInlineMenuOnFilledFieldTimeout() {
if (this.closeInlineMenuOnFilledFieldTimeout) {
globalThis.clearTimeout(this.closeInlineMenuOnFilledFieldTimeout);
}
}

/**
* Clears the timeout that facilitates recalculating the sub frame offsets.
*/
private clearRecalculateSubFrameOffsetsTimeout() {
if (this.recalculateSubFrameOffsetsTimeout) {
globalThis.clearTimeout(this.recalculateSubFrameOffsetsTimeout);
}
}

private clearFocusInlineMenuListTimeout() {
if (this.focusInlineMenuListTimeout) {
globalThis.clearTimeout(this.focusInlineMenuListTimeout);
Expand All @@ -1174,9 +1138,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
}

private clearAllTimeouts() {
this.clearUserInteractionEventTimeout();
this.clearCloseInlineMenuOnFilledFieldTimeout();
this.clearRecalculateSubFrameOffsetsTimeout();
this.clearFocusInlineMenuListTimeout();
this.clearCloseInlineMenuOnRedirectTimeout();
}
Expand Down

0 comments on commit f389263

Please sign in to comment.