[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
No known key found for this signature in database
GPG Key ID: 3381A5457F8CCECF
6 changed files with 40 additions and 22 deletions

View File

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

View File

@ -96,9 +96,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
};
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
closeAutofillInlineMenu: ({ port }) => this.closeInlineMenu(port.sender),
forceCloseAutofillInlineMenu: ({ port }) =>
this.closeInlineMenu(port.sender, { forceCloseAutofillInlineMenu: true }),
triggerDelayedInlineMenuClosure: ({ port }) =>
this.triggerDelayedInlineMenuClosure(port.sender),
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
this.redirectInlineMenuFocusOut(message, port),
@ -106,8 +105,6 @@ export class OverlayBackground implements OverlayBackgroundInterface {
};
private readonly inlineMenuListPortMessageHandlers: InlineMenuListPortMessageHandlers = {
checkAutofillInlineMenuButtonFocused: () => this.checkInlineMenuButtonFocused(),
forceCloseAutofillInlineMenu: ({ port }) =>
this.closeInlineMenu(port.sender, { forceCloseAutofillInlineMenu: true }),
autofillInlineMenuBlurred: () => this.checkInlineMenuButtonFocused(),
unlockVault: ({ port }) => this.unlockVault(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
* 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 ariaAlertElement: HTMLDivElement;
private ariaAlertTimeout: number | NodeJS.Timeout;
private delayedCloseTimeout: number | NodeJS.Timeout;
private readonly defaultOpacityTransition = "opacity 125ms ease-out 0s";
private iframeStyles: Partial<CSSStyleDeclaration> = {
all: "initial",
position: "fixed",
@ -23,7 +25,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
zIndex: "2147483647",
lineHeight: "0",
overflow: "hidden",
transition: "opacity 125ms ease-out 0s",
transition: this.defaultOpacityTransition,
visibility: "visible",
clipPath: "none",
pointerEvents: "auto",
@ -47,6 +49,7 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
updateInlineMenuIframePosition: ({ message }) => this.updateIframePosition(message.styles),
updateInlineMenuHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
updateAutofillInlineMenuColorScheme: () => this.updateAutofillInlineMenuColorScheme(),
triggerDelayedAutofillInlineMenuClosure: () => this.handleDelayedAutofillInlineMenuClosure(),
};
constructor(
@ -403,4 +406,24 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
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();
expect(globalThis.parent.postMessage).not.toHaveBeenCalledWith({
command: "closeAutofillInlineMenu",
command: "triggerDelayedInlineMenuClosure",
});
});
@ -85,7 +85,7 @@ describe("AutofillInlineMenuButton", () => {
await flushPromises();
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
{ command: "closeAutofillInlineMenu", portKey },
{ command: "triggerDelayedInlineMenuClosure", portKey },
"*",
);
});

View File

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

View File

@ -69,8 +69,6 @@ export class AutofillInlineMenuContainer {
private setupPortMessageListener = (message: InitInlineMenuElementMessage) => {
this.port = chrome.runtime.connect({ name: this.portName });
this.port.onMessage.addListener(this.handlePortMessage);
this.postMessageToInlineMenuPage(message);
};
@ -90,14 +88,6 @@ export class AutofillInlineMenuContainer {
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) => {
const message = event.data;
if (this.isForeignWindowMessage(event)) {