1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-25 21:51:30 +01:00

Revert "[PM-5189] Working through content script port improvement"

This reverts commit f389263b64.
This commit is contained in:
Cesar Gonzalez 2024-06-19 05:11:05 -05:00
parent 734f5f6aa4
commit 3181aadb8e
No known key found for this signature in database
GPG Key ID: 3381A5457F8CCECF
6 changed files with 76 additions and 24 deletions

View File

@ -98,7 +98,9 @@ export type OverlayBackgroundExtensionMessageHandlers = {
updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void; updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void;
checkIsFieldCurrentlyFilling: () => boolean; checkIsFieldCurrentlyFilling: () => boolean;
getAutofillInlineMenuVisibility: () => void; getAutofillInlineMenuVisibility: () => void;
closeAutofillInlineMenu: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
checkAutofillInlineMenuFocused: () => void;
focusAutofillInlineMenuList: () => void;
updateAutofillInlineMenuPosition: ({ updateAutofillInlineMenuPosition: ({
message, message,
sender, sender,
@ -141,14 +143,10 @@ export type OverlayContentScriptPortMessageHandlers = {
updateFocusedFieldData: ({ message, port }: PortOnMessageHandlerParams) => void; updateFocusedFieldData: ({ message, port }: PortOnMessageHandlerParams) => void;
updateIsFieldCurrentlyFocused: ({ message }: PortMessageParam) => void; updateIsFieldCurrentlyFocused: ({ message }: PortMessageParam) => void;
openAutofillInlineMenu: () => void; openAutofillInlineMenu: () => void;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
checkAutofillInlineMenuFocused: () => void;
focusAutofillInlineMenuList: () => void;
}; };
export type InlineMenuButtonPortMessageHandlers = { export type InlineMenuButtonPortMessageHandlers = {
[key: string]: CallableFunction; [key: string]: CallableFunction;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void; triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void;
autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void; autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void;
autofillInlineMenuBlurred: () => void; autofillInlineMenuBlurred: () => void;
@ -158,7 +156,6 @@ export type InlineMenuButtonPortMessageHandlers = {
export type InlineMenuListPortMessageHandlers = { export type InlineMenuListPortMessageHandlers = {
[key: string]: CallableFunction; [key: string]: CallableFunction;
closeAutofillInlineMenu: ({ message, port }: PortOnMessageHandlerParams) => void;
checkAutofillInlineMenuButtonFocused: () => void; checkAutofillInlineMenuButtonFocused: () => void;
autofillInlineMenuBlurred: () => void; autofillInlineMenuBlurred: () => void;
unlockVault: ({ port }: PortConnectionParam) => void; unlockVault: ({ port }: PortConnectionParam) => void;

View File

@ -82,7 +82,9 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateIsFieldCurrentlyFilling: ({ message }) => this.updateIsFieldCurrentlyFilling(message), updateIsFieldCurrentlyFilling: ({ message }) => this.updateIsFieldCurrentlyFilling(message),
checkIsFieldCurrentlyFilling: () => this.checkIsFieldCurrentlyFilling(), checkIsFieldCurrentlyFilling: () => this.checkIsFieldCurrentlyFilling(),
getAutofillInlineMenuVisibility: () => this.getInlineMenuVisibility(), getAutofillInlineMenuVisibility: () => this.getInlineMenuVisibility(),
closeAutofillInlineMenu: ({ message, sender }) => this.closeInlineMenu(sender, message),
checkAutofillInlineMenuFocused: () => this.checkInlineMenuFocused(),
focusAutofillInlineMenuList: () => this.focusInlineMenuList(),
updateAutofillInlineMenuPosition: ({ message, sender }) => updateAutofillInlineMenuPosition: ({ message, sender }) =>
this.updateInlineMenuPosition(message, sender), this.updateInlineMenuPosition(message, sender),
toggleAutofillInlineMenuHidden: ({ message, sender }) => toggleAutofillInlineMenuHidden: ({ message, sender }) =>
@ -109,12 +111,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateFocusedFieldData: ({ message, port }) => this.setFocusedFieldData(message, port), updateFocusedFieldData: ({ message, port }) => this.setFocusedFieldData(message, port),
updateIsFieldCurrentlyFocused: ({ message }) => this.updateIsFieldCurrentlyFocused(message), updateIsFieldCurrentlyFocused: ({ message }) => this.updateIsFieldCurrentlyFocused(message),
openAutofillInlineMenu: () => this.openInlineMenu(false), openAutofillInlineMenu: () => this.openInlineMenu(false),
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
checkAutofillInlineMenuFocused: () => this.checkInlineMenuFocused(),
focusAutofillInlineMenuList: () => this.focusInlineMenuList(),
}; };
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = { private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
triggerDelayedAutofillInlineMenuClosure: ({ port }) => this.triggerDelayedInlineMenuClosure(), triggerDelayedAutofillInlineMenuClosure: ({ port }) => this.triggerDelayedInlineMenuClosure(),
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port), autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(), autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
@ -123,7 +121,6 @@ export class OverlayBackground implements OverlayBackgroundInterface {
updateAutofillInlineMenuColorScheme: () => this.updateInlineMenuButtonColorScheme(), updateAutofillInlineMenuColorScheme: () => this.updateInlineMenuButtonColorScheme(),
}; };
private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = { private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = {
closeAutofillInlineMenu: ({ message, port }) => this.closeInlineMenu(port.sender, message),
checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(), checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(),
autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(), autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(),
unlockVault: ({ port }) => this.unlockVault(port), unlockVault: ({ port }) => this.unlockVault(port),

View File

@ -1,7 +1,7 @@
import { EVENTS } from "@bitwarden/common/autofill/constants"; import { EVENTS } from "@bitwarden/common/autofill/constants";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeType } from "@bitwarden/common/platform/enums";
import { setElementStyles } from "../../../utils"; import { sendExtensionMessage, setElementStyles } from "../../../utils";
import { import {
BackgroundPortMessageHandlers, BackgroundPortMessageHandlers,
AutofillInlineMenuIframeService as AutofillInlineMenuIframeServiceInterface, AutofillInlineMenuIframeService as AutofillInlineMenuIframeServiceInterface,
@ -10,6 +10,7 @@ import {
export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframeServiceInterface { export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframeServiceInterface {
private readonly setElementStyles = setElementStyles; private readonly setElementStyles = setElementStyles;
private readonly sendExtensionMessage = sendExtensionMessage;
private port: chrome.runtime.Port | null = null; private port: chrome.runtime.Port | null = null;
private portKey: string; private portKey: string;
private iframeMutationObserver: MutationObserver; private iframeMutationObserver: MutationObserver;
@ -304,7 +305,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
* mutation observer is triggered excessively. * mutation observer is triggered excessively.
*/ */
private forceCloseInlineMenu() { private forceCloseInlineMenu() {
void this.port.postMessage({ command: "closeAutofillInlineMenu", forceClose: true }); void this.sendExtensionMessage("closeAutofillInlineMenu", { forceClose: true });
} }
private handleFadeInInlineMenuIframe() { private handleFadeInInlineMenuIframe() {

View File

@ -44,7 +44,6 @@ export type AutofillOverlayContentExtensionMessage = {
overlayElement?: AutofillOverlayElementType; overlayElement?: AutofillOverlayElementType;
focusedFieldData?: FocusedFieldData; focusedFieldData?: FocusedFieldData;
isFieldCurrentlyFocused?: boolean; isFieldCurrentlyFocused?: boolean;
forceCloseInlineMenu?: boolean;
} & OverlayAddNewItemMessage; } & OverlayAddNewItemMessage;
export interface AutofillOverlayContentService { export interface AutofillOverlayContentService {

View File

@ -905,6 +905,17 @@ 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 () => { it("removes the overlay completely if the field is not focused", async () => {
jest.useFakeTimers(); jest.useFakeTimers();
jest jest
@ -1684,6 +1695,14 @@ describe("AutofillOverlayContentService", () => {
autofillOverlayContentService["mostRecentlyFocusedField"] = autofillFieldElement; 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", () => { it("de-registers all global event listeners", () => {
jest.spyOn(globalThis.document, "removeEventListener"); jest.spyOn(globalThis.document, "removeEventListener");
jest.spyOn(globalThis, "removeEventListener"); jest.spyOn(globalThis, "removeEventListener");

View File

@ -54,8 +54,11 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
private focusableElements: FocusableElement[] = []; private focusableElements: FocusableElement[] = [];
private mostRecentlyFocusedField: ElementWithOpId<FormFieldElement>; private mostRecentlyFocusedField: ElementWithOpId<FormFieldElement>;
private focusedFieldData: FocusedFieldData; private focusedFieldData: FocusedFieldData;
private userInteractionEventTimeout: number | NodeJS.Timeout;
private recalculateSubFrameOffsetsTimeout: number | NodeJS.Timeout;
private closeInlineMenuOnRedirectTimeout: number | NodeJS.Timeout; private closeInlineMenuOnRedirectTimeout: number | NodeJS.Timeout;
private focusInlineMenuListTimeout: number | NodeJS.Timeout; private focusInlineMenuListTimeout: number | NodeJS.Timeout;
private closeInlineMenuOnFilledFieldTimeout: number | NodeJS.Timeout;
private eventHandlersMemo: { [key: string]: EventListener } = {}; private eventHandlersMemo: { [key: string]: EventListener } = {};
private readonly extensionMessageHandlers: AutofillOverlayContentExtensionMessageHandlers = { private readonly extensionMessageHandlers: AutofillOverlayContentExtensionMessageHandlers = {
openAutofillInlineMenu: ({ message }) => this.openInlineMenu(message), openAutofillInlineMenu: ({ message }) => this.openInlineMenu(message),
@ -204,7 +207,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.mostRecentlyFocusedField?.blur(); this.mostRecentlyFocusedField?.blur();
if (isClosingInlineMenu) { if (isClosingInlineMenu) {
this.sendPortMessage("closeAutofillInlineMenu"); void this.sendExtensionMessage("closeAutofillInlineMenu");
} }
} }
@ -249,7 +252,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
if (direction === RedirectFocusDirection.Current) { if (direction === RedirectFocusDirection.Current) {
this.focusMostRecentlyFocusedField(); this.focusMostRecentlyFocusedField();
this.closeInlineMenuOnRedirectTimeout = globalThis.setTimeout( this.closeInlineMenuOnRedirectTimeout = globalThis.setTimeout(
() => this.sendPortMessage("closeAutofillInlineMenu"), () => void this.sendExtensionMessage("closeAutofillInlineMenu"),
100, 100,
); );
return; return;
@ -347,7 +350,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.sendPortMessage("updateIsFieldCurrentlyFocused", { this.sendPortMessage("updateIsFieldCurrentlyFocused", {
isFieldCurrentlyFocused: false, isFieldCurrentlyFocused: false,
}); });
this.sendPortMessage("checkAutofillInlineMenuFocused"); void this.sendExtensionMessage("checkAutofillInlineMenuFocused");
}; };
/** /**
@ -361,7 +364,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
private handleFormFieldKeyupEvent = async (event: KeyboardEvent) => { private handleFormFieldKeyupEvent = async (event: KeyboardEvent) => {
const eventCode = event.code; const eventCode = event.code;
if (eventCode === "Escape") { if (eventCode === "Escape") {
this.sendPortMessage("closeAutofillInlineMenu", { void this.sendExtensionMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true, forceCloseInlineMenu: true,
}); });
return; return;
@ -391,13 +394,13 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField); await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
this.openInlineMenu({ isOpeningFullInlineMenu: true }); this.openInlineMenu({ isOpeningFullInlineMenu: true });
this.focusInlineMenuListTimeout = globalThis.setTimeout( this.focusInlineMenuListTimeout = globalThis.setTimeout(
() => this.sendPortMessage("focusAutofillInlineMenuList"), () => this.sendExtensionMessage("focusAutofillInlineMenuList"),
125, 125,
); );
return; return;
} }
this.sendPortMessage("focusAutofillInlineMenuList"); void this.sendExtensionMessage("focusAutofillInlineMenuList");
} }
/** /**
@ -427,7 +430,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.storeModifiedFormElement(formFieldElement); this.storeModifiedFormElement(formFieldElement);
if (await this.hideInlineMenuListOnFilledField(formFieldElement)) { if (await this.hideInlineMenuListOnFilledField(formFieldElement)) {
this.sendPortMessage("closeAutofillInlineMenu", { void this.sendExtensionMessage("closeAutofillInlineMenu", {
overlayElement: AutofillOverlayElement.List, overlayElement: AutofillOverlayElement.List,
forceCloseInlineMenu: true, forceCloseInlineMenu: true,
}); });
@ -511,6 +514,13 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.sendPortMessage("updateIsFieldCurrentlyFocused", { this.sendPortMessage("updateIsFieldCurrentlyFocused", {
isFieldCurrentlyFocused: true, isFieldCurrentlyFocused: true,
}); });
if (this.userInteractionEventTimeout) {
this.clearUserInteractionEventTimeout();
void this.toggleInlineMenuHidden(false, true);
void this.sendExtensionMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true,
});
}
const initiallyFocusedField = this.mostRecentlyFocusedField; const initiallyFocusedField = this.mostRecentlyFocusedField;
await this.updateMostRecentlyFocusedField(formFieldElement); await this.updateMostRecentlyFocusedField(formFieldElement);
@ -519,7 +529,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
(initiallyFocusedField !== this.mostRecentlyFocusedField && (initiallyFocusedField !== this.mostRecentlyFocusedField &&
(await this.hideInlineMenuListOnFilledField(formFieldElement as FillableFormFieldElement))) (await this.hideInlineMenuListOnFilledField(formFieldElement as FillableFormFieldElement)))
) { ) {
this.sendPortMessage("closeAutofillInlineMenu", { await this.sendExtensionMessage("closeAutofillInlineMenu", {
overlayElement: AutofillOverlayElement.List, overlayElement: AutofillOverlayElement.List,
forceCloseInlineMenu: true, forceCloseInlineMenu: true,
}); });
@ -1007,7 +1017,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
} }
this.unsetMostRecentlyFocusedField(); this.unsetMostRecentlyFocusedField();
this.sendPortMessage("closeAutofillInlineMenu", { void this.sendExtensionMessage("closeAutofillInlineMenu", {
forceCloseInlineMenu: true, forceCloseInlineMenu: true,
}); });
}; };
@ -1125,6 +1135,32 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
this.port.postMessage({ command, ...message }); 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() { private clearFocusInlineMenuListTimeout() {
if (this.focusInlineMenuListTimeout) { if (this.focusInlineMenuListTimeout) {
globalThis.clearTimeout(this.focusInlineMenuListTimeout); globalThis.clearTimeout(this.focusInlineMenuListTimeout);
@ -1138,6 +1174,9 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
} }
private clearAllTimeouts() { private clearAllTimeouts() {
this.clearUserInteractionEventTimeout();
this.clearCloseInlineMenuOnFilledFieldTimeout();
this.clearRecalculateSubFrameOffsetsTimeout();
this.clearFocusInlineMenuListTimeout(); this.clearFocusInlineMenuListTimeout();
this.clearCloseInlineMenuOnRedirectTimeout(); this.clearCloseInlineMenuOnRedirectTimeout();
} }