1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 16:23:44 +00:00

[PM-5189] Fixing issue with programmatic redirection of the inlne menu

This commit is contained in:
Cesar Gonzalez
2024-06-05 04:38:27 -05:00
parent ce593e024d
commit b2ab42e1a4
6 changed files with 40 additions and 22 deletions

View File

@@ -131,8 +131,7 @@ export type PortOnMessageHandlerParams = PortMessageParam & PortConnectionParam;
export type InlineMenuButtonPortMessageHandlers = { export type InlineMenuButtonPortMessageHandlers = {
[key: string]: CallableFunction; [key: string]: CallableFunction;
autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void; autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void;
closeAutofillInlineMenu: ({ port }: PortConnectionParam) => void; triggerDelayedInlineMenuClosure: ({ port }: PortConnectionParam) => void;
forceCloseAutofillInlineMenu: ({ port }: PortConnectionParam) => void;
autofillInlineMenuBlurred: () => void; autofillInlineMenuBlurred: () => void;
redirectAutofillInlineMenuFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void; redirectAutofillInlineMenuFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void;
updateAutofillInlineMenuColorScheme: () => void; updateAutofillInlineMenuColorScheme: () => void;
@@ -141,7 +140,6 @@ export type InlineMenuButtonPortMessageHandlers = {
export type InlineMenuListPortMessageHandlers = { export type InlineMenuListPortMessageHandlers = {
[key: string]: CallableFunction; [key: string]: CallableFunction;
checkAutofillInlineMenuButtonFocused: () => void; checkAutofillInlineMenuButtonFocused: () => void;
forceCloseAutofillInlineMenu: ({ port }: PortConnectionParam) => void;
autofillInlineMenuBlurred: () => void; autofillInlineMenuBlurred: () => void;
unlockVault: ({ port }: PortConnectionParam) => void; unlockVault: ({ port }: PortConnectionParam) => void;
fillSelectedAutofillInlineMenuListItem: ({ message, port }: PortOnMessageHandlerParams) => void; fillSelectedAutofillInlineMenuListItem: ({ message, port }: PortOnMessageHandlerParams) => void;

View File

@@ -96,9 +96,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
}; };
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = { private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port), autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
closeAutofillInlineMenu: ({ port }) => this.closeInlineMenu(port.sender), triggerDelayedInlineMenuClosure: ({ port }) =>
forceCloseAutofillInlineMenu: ({ port }) => this.triggerDelayedInlineMenuClosure(port.sender),
this.closeInlineMenu(port.sender, { forceCloseAutofillInlineMenu: true }),
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(), autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
redirectAutofillInlineMenuFocusOut: ({ message, port }) => redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
this.redirectInlineMenuFocusOut(message, port), this.redirectInlineMenuFocusOut(message, port),
@@ -106,8 +105,6 @@ export class OverlayBackground implements OverlayBackgroundInterface {
}; };
private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = { private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = {
checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(), checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(),
forceCloseAutofillInlineMenu: ({ port }) =>
this.closeInlineMenu(port.sender, { forceCloseAutofillInlineMenu: true }),
autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(), autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(),
unlockVault: ({ port }) => this.unlockVault(port), unlockVault: ({ port }) => this.unlockVault(port),
fillSelectedAutofillInlineMenuListItem: ({ message, port }) => fillSelectedAutofillInlineMenuListItem: ({ message, port }) =>
@@ -510,6 +507,16 @@ export class OverlayBackground implements OverlayBackgroundInterface {
); );
} }
private triggerDelayedInlineMenuClosure(sender: chrome.runtime.MessageSender) {
if (this.isFieldCurrentlyFocused) {
return;
}
const message = { command: "triggerDelayedAutofillInlineMenuClosure" };
this.inlineMenuButtonPort?.postMessage(message);
this.inlineMenuListPort?.postMessage(message);
}
/** /**
* Handles cleanup when an overlay element is closed. Disconnects * Handles cleanup when an overlay element is closed. Disconnects
* the list and button ports and sets them to null. * the list and button ports and sets them to null.

View File

@@ -16,6 +16,8 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
private iframe: HTMLIFrameElement; private iframe: HTMLIFrameElement;
private ariaAlertElement: HTMLDivElement; private ariaAlertElement: HTMLDivElement;
private ariaAlertTimeout: number | NodeJS.Timeout; private ariaAlertTimeout: number | NodeJS.Timeout;
private delayedCloseTimeout: number | NodeJS.Timeout;
private readonly defaultOpacityTransition = "opacity 125ms ease-out 0s";
private iframeStyles: Partial<CSSStyleDeclaration> = { private iframeStyles: Partial<CSSStyleDeclaration> = {
all: "initial", all: "initial",
position: "fixed", position: "fixed",
@@ -23,7 +25,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
zIndex: "2147483647", zIndex: "2147483647",
lineHeight: "0", lineHeight: "0",
overflow: "hidden", overflow: "hidden",
transition: "opacity 125ms ease-out 0s", transition: this.defaultOpacityTransition,
visibility: "visible", visibility: "visible",
clipPath: "none", clipPath: "none",
pointerEvents: "auto", pointerEvents: "auto",
@@ -47,6 +49,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
updateInlineMenuIframePosition: ({ message }) => this.updateIframePosition(message.styles), updateInlineMenuIframePosition: ({ message }) => this.updateIframePosition(message.styles),
updateInlineMenuHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles), updateInlineMenuHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
updateAutofillInlineMenuColorScheme: () => this.updateAutofillInlineMenuColorScheme(), updateAutofillInlineMenuColorScheme: () => this.updateAutofillInlineMenuColorScheme(),
triggerDelayedAutofillInlineMenuClosure: () => this.handleDelayedAutofillInlineMenuClosure(),
}; };
constructor( constructor(
@@ -403,4 +406,24 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
return false; return false;
} }
private handleDelayedAutofillInlineMenuClosure() {
if (this.delayedCloseTimeout) {
clearTimeout(this.delayedCloseTimeout);
}
this.updateElementStyles(this.iframe, {
opacity: "0",
transition: "none",
pointerEvents: "none",
});
this.delayedCloseTimeout = globalThis.setTimeout(() => {
this.updateElementStyles(this.iframe, {
transition: this.defaultOpacityTransition,
pointerEvents: "auto",
});
this.forceCloseAutofillInlineMenu();
}, 250);
}
} }

View File

@@ -74,7 +74,7 @@ describe("AutofillInlineMenuButton", () => {
await flushPromises(); await flushPromises();
expect(globalThis.parent.postMessage).not.toHaveBeenCalledWith({ expect(globalThis.parent.postMessage).not.toHaveBeenCalledWith({
command: "closeAutofillInlineMenu", command: "triggerDelayedInlineMenuClosure",
}); });
}); });
@@ -85,7 +85,7 @@ describe("AutofillInlineMenuButton", () => {
await flushPromises(); await flushPromises();
expect(globalThis.parent.postMessage).toHaveBeenCalledWith( expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
{ command: "closeAutofillInlineMenu", portKey }, { command: "triggerDelayedInlineMenuClosure", portKey },
"*", "*",
); );
}); });

View File

@@ -121,7 +121,7 @@ class AutofillInlineMenuButton extends AutofillInlineMenuPageElement {
return; return;
} }
this.postMessageToParent({ command: "closeAutofillInlineMenu" }); this.postMessageToParent({ command: "triggerDelayedInlineMenuClosure" });
} }
} }

View File

@@ -69,8 +69,6 @@ export class AutofillInlineMenuContainer {
private setupPortMessageListener = (message: InitInlineMenuElementMessage) => { private setupPortMessageListener = (message: InitInlineMenuElementMessage) => {
this.port = chrome.runtime.connect({ name: this.portName }); this.port = chrome.runtime.connect({ name: this.portName });
this.port.onMessage.addListener(this.handlePortMessage);
this.postMessageToInlineMenuPage(message); this.postMessageToInlineMenuPage(message);
}; };
@@ -90,14 +88,6 @@ export class AutofillInlineMenuContainer {
this.port.postMessage(message); this.port.postMessage(message);
} }
private handlePortMessage = (message: any, port: chrome.runtime.Port) => {
if (port.name !== this.portName) {
return;
}
this.postMessageToInlineMenuPage(message);
};
private handleWindowMessage = (event: MessageEvent) => { private handleWindowMessage = (event: MessageEvent) => {
const message = event.data; const message = event.data;
if (this.isForeignWindowMessage(event)) { if (this.isForeignWindowMessage(event)) {