mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
[PM-5189] Separating the inline menu UI elements from the base AutofillOverlayContentService and setting up messaging to allow for propagation of those elements
This commit is contained in:
@@ -48,6 +48,8 @@ type OverlayBackgroundExtensionMessage = {
|
||||
forceCloseOverlay?: boolean;
|
||||
isOverlayHidden?: boolean;
|
||||
data?: LockedVaultPendingNotificationsData;
|
||||
isFieldCurrentlyFocused?: boolean;
|
||||
isCurrentlyFilling?: boolean;
|
||||
} & OverlayAddNewItemMessage;
|
||||
|
||||
type OverlayPortMessage = {
|
||||
@@ -102,6 +104,12 @@ type OverlayBackgroundExtensionMessageHandlers = {
|
||||
unlockCompleted: ({ message }: BackgroundMessageParam) => void;
|
||||
addEditCipherSubmitted: () => void;
|
||||
deletedCipher: () => void;
|
||||
checkIsFieldCurrentlyFocused: () => boolean;
|
||||
checkIsFieldCurrentlyFilling: () => boolean;
|
||||
updateIsFieldCurrentlyFocused: ({ message }: BackgroundMessageParam) => void;
|
||||
updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void;
|
||||
checkIsInlineMenuButtonVisible: ({ sender }: BackgroundSenderParam) => void;
|
||||
checkIsInlineMenuListVisible: ({ sender }: BackgroundSenderParam) => void;
|
||||
};
|
||||
|
||||
type PortMessageParam = {
|
||||
|
||||
@@ -76,6 +76,14 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
unlockCompleted: ({ message }) => this.unlockCompleted(message),
|
||||
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
|
||||
deletedCipher: () => this.updateOverlayCiphers(),
|
||||
checkIsFieldCurrentlyFocused: () => this.isFieldCurrentlyFocused,
|
||||
checkIsFieldCurrentlyFilling: () => this.isCurrentlyFilling,
|
||||
updateIsFieldCurrentlyFocused: ({ message }) =>
|
||||
(this.isFieldCurrentlyFocused = message.isFieldCurrentlyFocused),
|
||||
updateIsFieldCurrentlyFilling: ({ message }) =>
|
||||
(this.isCurrentlyFilling = message.isFieldCurrentlyFilling),
|
||||
checkIsInlineMenuButtonVisible: ({ sender }) => this.checkIsInlineMenuButtonVisible(sender),
|
||||
checkIsInlineMenuListVisible: ({ sender }) => this.checkIsInlineMenuListVisible(sender),
|
||||
};
|
||||
private readonly overlayButtonPortMessageHandlers: OverlayButtonPortMessageHandlers = {
|
||||
overlayButtonClicked: ({ port }) => this.handleOverlayButtonClicked(port),
|
||||
@@ -112,6 +120,23 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
this.iconsServerUrl = this.environmentService.getIconsUrl();
|
||||
}
|
||||
|
||||
private async checkIsInlineMenuButtonVisible(sender: chrome.runtime.MessageSender) {
|
||||
const value = await BrowserApi.tabSendMessage(
|
||||
sender.tab,
|
||||
{ command: "checkIsInlineMenuButtonVisible" },
|
||||
{ frameId: 0 },
|
||||
);
|
||||
return value;
|
||||
}
|
||||
|
||||
private async checkIsInlineMenuListVisible(sender: chrome.runtime.MessageSender) {
|
||||
return await BrowserApi.tabSendMessage(
|
||||
sender.tab,
|
||||
{ command: "checkIsInlineMenuListVisible" },
|
||||
{ frameId: 0 },
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes cached page details for a tab
|
||||
* based on the passed tabId.
|
||||
@@ -414,7 +439,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
|
||||
await BrowserApi.tabSendMessage(
|
||||
sender.tab,
|
||||
{ command: "updateInlineMenuElementsPosition" },
|
||||
{ command: "updateInlineMenuElementsPosition", overlayElement },
|
||||
{ frameId: 0 },
|
||||
);
|
||||
|
||||
@@ -827,14 +852,14 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
translations: this.getTranslations(),
|
||||
ciphers: isOverlayListPort ? await this.getOverlayCipherData() : null,
|
||||
});
|
||||
void this.updateOverlayPosition(
|
||||
{
|
||||
overlayElement: isOverlayListPort
|
||||
? AutofillOverlayElement.List
|
||||
: AutofillOverlayElement.Button,
|
||||
},
|
||||
port.sender,
|
||||
);
|
||||
// void this.updateOverlayPosition(
|
||||
// {
|
||||
// overlayElement: isOverlayListPort
|
||||
// ? AutofillOverlayElement.List
|
||||
// : AutofillOverlayElement.Button,
|
||||
// },
|
||||
// port.sender,
|
||||
// );
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ export type AutofillExtensionMessage = {
|
||||
pageDetailsUrl?: string;
|
||||
ciphers?: any;
|
||||
isInlineMenuHidden?: boolean;
|
||||
overlayElement?: string;
|
||||
data?: {
|
||||
authStatus?: AuthenticationStatus;
|
||||
isFocusingFieldElement?: boolean;
|
||||
|
||||
@@ -143,27 +143,18 @@ class AutofillInit implements AutofillInitInterface {
|
||||
}
|
||||
|
||||
this.blurAndRemoveOverlay();
|
||||
this.updateOverlayIsCurrentlyFilling(true);
|
||||
await sendExtensionMessage("updateIsFieldCurrentlyFilling", { isFieldCurrentlyFilling: true });
|
||||
await this.insertAutofillContentService.fillForm(fillScript);
|
||||
|
||||
if (!this.autofillOverlayContentService) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => this.updateOverlayIsCurrentlyFilling(false), 250);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles updating the overlay is currently filling value.
|
||||
*
|
||||
* @param isCurrentlyFilling - Indicates if the overlay is currently filling
|
||||
*/
|
||||
private updateOverlayIsCurrentlyFilling(isCurrentlyFilling: boolean) {
|
||||
if (!this.autofillOverlayContentService) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.autofillOverlayContentService.isCurrentlyFilling = isCurrentlyFilling;
|
||||
setTimeout(
|
||||
() =>
|
||||
sendExtensionMessage("updateIsFieldCurrentlyFilling", { isFieldCurrentlyFilling: false }),
|
||||
250,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,8 +3,10 @@ import { AutofillExtensionMessageParam } from "../../content/abstractions/autofi
|
||||
export type InlineMenuExtensionMessageHandlers = {
|
||||
[key: string]: CallableFunction;
|
||||
closeInlineMenu: ({ message }: AutofillExtensionMessageParam) => void;
|
||||
updateInlineMenuElementsPosition: () => Promise<[void, void]>;
|
||||
updateInlineMenuElementsPosition: ({ message }: AutofillExtensionMessageParam) => Promise<void>;
|
||||
toggleInlineMenuHidden: ({ message }: AutofillExtensionMessageParam) => void;
|
||||
checkIsInlineMenuButtonVisible: () => boolean;
|
||||
checkIsInlineMenuListVisible: () => boolean;
|
||||
};
|
||||
|
||||
export interface InlineMenuElements {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AutofillExtensionMessage } from "../../content/abstractions/autofill-init";
|
||||
import {
|
||||
sendExtensionMessage,
|
||||
generateRandomCustomElementName,
|
||||
@@ -35,9 +36,12 @@ export class InlineMenuElements implements InlineMenuElementsInterface {
|
||||
};
|
||||
private readonly _extensionMessageHandlers: InlineMenuExtensionMessageHandlers = {
|
||||
closeInlineMenu: ({ message }) => this.removeInlineMenu(),
|
||||
updateInlineMenuElementsPosition: () => this.updateInlineMenuElementsPosition(),
|
||||
updateInlineMenuElementsPosition: ({ message }) =>
|
||||
this.updateInlineMenuElementsPosition(message),
|
||||
toggleInlineMenuHidden: ({ message }) =>
|
||||
this.toggleInlineMenuHidden(message.isInlineMenuHidden),
|
||||
checkIsInlineMenuButtonVisible: () => this.isButtonVisible,
|
||||
checkIsInlineMenuListVisible: () => this.isListVisible,
|
||||
};
|
||||
|
||||
constructor() {
|
||||
@@ -107,8 +111,12 @@ export class InlineMenuElements implements InlineMenuElementsInterface {
|
||||
/**
|
||||
* Updates the position of both the overlay button and overlay list.
|
||||
*/
|
||||
private async updateInlineMenuElementsPosition() {
|
||||
return Promise.all([this.updateButtonPosition(), this.updateListPosition()]);
|
||||
private async updateInlineMenuElementsPosition({ overlayElement }: AutofillExtensionMessage) {
|
||||
if (overlayElement === AutofillOverlayElement.Button) {
|
||||
return this.updateButtonPosition();
|
||||
}
|
||||
|
||||
return this.updateListPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -245,7 +245,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
|
||||
}
|
||||
|
||||
this.updateElementStyles(this.iframe, position);
|
||||
setTimeout(() => this.updateElementStyles(this.iframe, { opacity: "1" }), 75);
|
||||
setTimeout(() => this.updateElementStyles(this.iframe, { opacity: "1" }), 0);
|
||||
this.announceAriaAlert();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ export type AutofillOverlayContentExtensionMessageHandlers = {
|
||||
};
|
||||
|
||||
export interface AutofillOverlayContentService {
|
||||
isFieldCurrentlyFocused: boolean;
|
||||
isCurrentlyFilling: boolean;
|
||||
// isFieldCurrentlyFocused: boolean;
|
||||
// isCurrentlyFilling: boolean;
|
||||
isOverlayCiphersPopulated: boolean;
|
||||
pageDetailsUpdateRequired: boolean;
|
||||
autofillOverlayVisibility: number;
|
||||
|
||||
@@ -26,8 +26,8 @@ import {
|
||||
import { AutoFillConstants } from "./autofill-constants";
|
||||
|
||||
class AutofillOverlayContentService implements AutofillOverlayContentServiceInterface {
|
||||
isFieldCurrentlyFocused = false;
|
||||
isCurrentlyFilling = false;
|
||||
// isFieldCurrentlyFocused = false;
|
||||
// isCurrentlyFilling = false;
|
||||
isOverlayCiphersPopulated = false;
|
||||
pageDetailsUpdateRequired = false;
|
||||
autofillOverlayVisibility: number;
|
||||
@@ -42,8 +42,8 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
private userFilledFields: Record<string, FillableFormFieldElement> = {};
|
||||
private authStatus: AuthenticationStatus;
|
||||
private focusableElements: FocusableElement[] = [];
|
||||
private isOverlayButtonVisible = false;
|
||||
private isOverlayListVisible = false;
|
||||
// private isOverlayButtonVisible = false;
|
||||
// private isOverlayListVisible = false;
|
||||
// private overlayButtonElement: HTMLElement;
|
||||
// private overlayListElement: HTMLElement;
|
||||
private mostRecentlyFocusedField: ElementWithOpId<FormFieldElement>;
|
||||
@@ -217,8 +217,9 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* Formats any found user filled fields for a login cipher and sends a message
|
||||
* to the background script to add a new cipher.
|
||||
*/
|
||||
addNewVaultItem() {
|
||||
if (!this.isOverlayListVisible) {
|
||||
async addNewVaultItem() {
|
||||
// if (!this.isOverlayListVisible) {
|
||||
if ((await this.sendExtensionMessage("checkIsInlineMenuListVisible")) !== true) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -239,8 +240,12 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
*
|
||||
* @param direction - The direction to redirect the focus.
|
||||
*/
|
||||
redirectOverlayFocusOut(direction: string) {
|
||||
if (!this.isOverlayListVisible || !this.mostRecentlyFocusedField) {
|
||||
async redirectOverlayFocusOut(direction: string) {
|
||||
// if (!this.isOverlayListVisible || !this.mostRecentlyFocusedField) {
|
||||
if (
|
||||
!this.mostRecentlyFocusedField ||
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuListVisible")) !== true
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -340,7 +345,10 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* is currently focused.
|
||||
*/
|
||||
private handleFormFieldBlurEvent = () => {
|
||||
this.isFieldCurrentlyFocused = false;
|
||||
// this.isFieldCurrentlyFocused = false;
|
||||
void this.sendExtensionMessage("updateIsFieldCurrentlyFocused", {
|
||||
isFieldCurrentlyFocused: false,
|
||||
});
|
||||
void this.sendExtensionMessage("checkAutofillOverlayFocused");
|
||||
};
|
||||
|
||||
@@ -352,7 +360,7 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
*
|
||||
* @param event - The keyup event.
|
||||
*/
|
||||
private handleFormFieldKeyupEvent = (event: KeyboardEvent) => {
|
||||
private handleFormFieldKeyupEvent = async (event: KeyboardEvent) => {
|
||||
const eventCode = event.code;
|
||||
if (eventCode === "Escape") {
|
||||
// this.removeAutofillOverlay();
|
||||
@@ -360,8 +368,12 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventCode === "Enter" && !this.isCurrentlyFilling) {
|
||||
this.handleOverlayRepositionEvent();
|
||||
// if (eventCode === "Enter" && !this.isCurrentlyFilling) {
|
||||
if (
|
||||
eventCode === "Enter" &&
|
||||
!(await this.sendExtensionMessage("checkIsFieldCurrentlyFilling")) === true
|
||||
) {
|
||||
void this.handleOverlayRepositionEvent();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -381,7 +393,11 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* that the overlay list is focused when the user presses the down arrow key.
|
||||
*/
|
||||
private async focusOverlayList() {
|
||||
if (!this.isOverlayListVisible && this.mostRecentlyFocusedField) {
|
||||
// if (!this.isOverlayListVisible && this.mostRecentlyFocusedField) {
|
||||
if (
|
||||
this.mostRecentlyFocusedField &&
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuListVisible")) !== true
|
||||
) {
|
||||
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
||||
this.openAutofillOverlay({ isOpeningFullOverlay: true });
|
||||
setTimeout(() => this.sendExtensionMessage("focusAutofillOverlayList"), 125);
|
||||
@@ -470,7 +486,11 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* @param formFieldElement - The form field element that triggered the click event.
|
||||
*/
|
||||
private async triggerFormFieldClickedAction(formFieldElement: ElementWithOpId<FormFieldElement>) {
|
||||
if (this.isOverlayButtonVisible || this.isOverlayListVisible) {
|
||||
// if (this.isOverlayButtonVisible || this.isOverlayListVisible) {
|
||||
if (
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuButtonVisible")) === true ||
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuListVisible")) === true
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -497,11 +517,15 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* @param formFieldElement - The form field element that triggered the focus event.
|
||||
*/
|
||||
private async triggerFormFieldFocusedAction(formFieldElement: ElementWithOpId<FormFieldElement>) {
|
||||
if (this.isCurrentlyFilling) {
|
||||
// if (this.isCurrentlyFilling) {
|
||||
if ((await this.sendExtensionMessage("checkIsFieldCurrentlyFilling")) === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isFieldCurrentlyFocused = true;
|
||||
// this.isFieldCurrentlyFocused = true;
|
||||
void this.sendExtensionMessage("updateIsFieldCurrentlyFocused", {
|
||||
isFieldCurrentlyFocused: true,
|
||||
});
|
||||
this.clearUserInteractionEventTimeout();
|
||||
const initiallyFocusedField = this.mostRecentlyFocusedField;
|
||||
await this.updateMostRecentlyFocusedField(formFieldElement);
|
||||
@@ -848,8 +872,12 @@ class AutofillOverlayContentService implements AutofillOverlayContentServiceInte
|
||||
* Handles the resize or scroll events that enact
|
||||
* repositioning of the overlay.
|
||||
*/
|
||||
private handleOverlayRepositionEvent = () => {
|
||||
if (!this.isOverlayButtonVisible && !this.isOverlayListVisible) {
|
||||
private handleOverlayRepositionEvent = async () => {
|
||||
// if (!this.isOverlayButtonVisible && !this.isOverlayListVisible) {
|
||||
if (
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuButtonVisible")) !== true &&
|
||||
(await this.sendExtensionMessage("checkIsInlineMenuListVisible")) !== true
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user