mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
[PM-12345] Add cipher type settings for inline autofill menu (#11260)
* add inline menu identity and card visibility settings state to autofill settings service * add inline menu identity and card visibility settings to autofill settings view component * add inline menu identity and card visibility settings to legacy autofill settings view component * do not show inline menu card and identity visibility settings if inline-menu-positioning-improvements feature flag is off * show card and identity inline menus based on their visibility settings * do not show identities in account creation username/email fields if user setting disallows it * reload local tab settings for inline menu visibility when an inline visibility setting value changes * take out tabSendMessageData call for inline menu visibility sub-settings --------- Co-authored-by: Cesar Gonzalez <cesar.a.gonzalezcs@gmail.com>
This commit is contained in:
parent
40ab96a7ce
commit
1c2cb4440b
@ -1408,6 +1408,12 @@
|
||||
"showInlineMenuLabel": {
|
||||
"message": "Show autofill suggestions on form fields"
|
||||
},
|
||||
"showInlineMenuIdentitiesLabel": {
|
||||
"message": "Display identities as suggestions"
|
||||
},
|
||||
"showInlineMenuCardsLabel": {
|
||||
"message": "Display cards as suggestions"
|
||||
},
|
||||
"showInlineMenuOnIconSelectionLabel": {
|
||||
"message": "Display suggestions when icon is selected"
|
||||
},
|
||||
|
@ -188,6 +188,8 @@ export type OverlayBackgroundExtensionMessageHandlers = {
|
||||
updateIsFieldCurrentlyFilling: ({ message }: BackgroundMessageParam) => void;
|
||||
checkIsFieldCurrentlyFilling: () => boolean;
|
||||
getAutofillInlineMenuVisibility: () => void;
|
||||
getInlineMenuCardsVisibility: () => void;
|
||||
getInlineMenuIdentitiesVisibility: () => void;
|
||||
openAutofillInlineMenu: () => void;
|
||||
closeAutofillInlineMenu: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
|
||||
checkAutofillInlineMenuFocused: ({ sender }: BackgroundSenderParam) => void;
|
||||
|
@ -132,6 +132,8 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||
updateIsFieldCurrentlyFilling: ({ message }) => this.updateIsFieldCurrentlyFilling(message),
|
||||
checkIsFieldCurrentlyFilling: () => this.checkIsFieldCurrentlyFilling(),
|
||||
getAutofillInlineMenuVisibility: () => this.getInlineMenuVisibility(),
|
||||
getInlineMenuCardsVisibility: () => this.getInlineMenuCardsVisibility(),
|
||||
getInlineMenuIdentitiesVisibility: () => this.getInlineMenuIdentitiesVisibility(),
|
||||
openAutofillInlineMenu: () => this.openInlineMenu(false),
|
||||
closeAutofillInlineMenu: ({ message, sender }) => this.closeInlineMenu(sender, message),
|
||||
checkAutofillInlineMenuFocused: ({ sender }) => this.checkInlineMenuFocused(sender),
|
||||
@ -1483,6 +1485,20 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||
return await firstValueFrom(this.autofillSettingsService.inlineMenuVisibility$);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inline menu's visibility setting for Cards from the settings service.
|
||||
*/
|
||||
private async getInlineMenuCardsVisibility(): Promise<boolean> {
|
||||
return await firstValueFrom(this.autofillSettingsService.showInlineMenuCards$);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the inline menu's visibility setting for Identities from the settings service.
|
||||
*/
|
||||
private async getInlineMenuIdentitiesVisibility(): Promise<boolean> {
|
||||
return await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user's authentication status from the auth service.
|
||||
*/
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
|
||||
import { AutofillOverlayElementType } from "../../enums/autofill-overlay.enum";
|
||||
@ -23,7 +24,7 @@ export type AutofillExtensionMessage = {
|
||||
data?: {
|
||||
direction?: "previous" | "next" | "current";
|
||||
forceCloseInlineMenu?: boolean;
|
||||
inlineMenuVisibility?: number;
|
||||
newSettingValue?: InlineMenuVisibilitySetting;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,32 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box tw-mb-5" *ngIf="inlineMenuPositioningImprovementsEnabled && inlineMenuIsEnabled">
|
||||
<div class="box-content">
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
<label for="show-inline-menu-identities" class="!tw-mr-0">{{
|
||||
"showInlineMenuIdentitiesLabel" | i18n
|
||||
}}</label>
|
||||
<input
|
||||
id="show-inline-menu-identities"
|
||||
type="checkbox"
|
||||
(change)="updateShowInlineMenuIdentities()"
|
||||
[(ngModel)]="showInlineMenuIdentities"
|
||||
/>
|
||||
</div>
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
<label for="show-inline-menu-cards" class="!tw-mr-0">{{
|
||||
"showInlineMenuCardsLabel" | i18n
|
||||
}}</label>
|
||||
<input
|
||||
id="show-inline-menu-cards"
|
||||
type="checkbox"
|
||||
(change)="updateShowInlineMenuCards()"
|
||||
[(ngModel)]="showInlineMenuCards"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-content" *ngIf="canOverrideBrowserAutofillSetting">
|
||||
<div class="box-content-row box-content-row-checkbox" appBoxRow>
|
||||
|
@ -8,10 +8,12 @@ import {
|
||||
InlineMenuVisibilitySetting,
|
||||
ClearClipboardDelaySetting,
|
||||
} from "@bitwarden/common/autofill/types";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import {
|
||||
UriMatchStrategy,
|
||||
UriMatchStrategySetting,
|
||||
} from "@bitwarden/common/models/domain/domain-service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -20,7 +22,6 @@ import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BrowserApi } from "../../../platform/browser/browser-api";
|
||||
import { enableAccountSwitching } from "../../../platform/flags";
|
||||
import { AutofillService } from "../../services/abstractions/autofill.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-autofill-v1",
|
||||
@ -32,6 +33,10 @@ export class AutofillV1Component implements OnInit {
|
||||
protected autoFillOverlayVisibility: InlineMenuVisibilitySetting;
|
||||
protected autoFillOverlayVisibilityOptions: any[];
|
||||
protected disablePasswordManagerLink: string;
|
||||
protected inlineMenuPositioningImprovementsEnabled: boolean = false;
|
||||
protected showInlineMenuIdentities: boolean = true;
|
||||
protected showInlineMenuCards: boolean = true;
|
||||
inlineMenuIsEnabled: boolean = false;
|
||||
enableAutoFillOnPageLoad = false;
|
||||
autoFillOnPageLoadDefault = false;
|
||||
autoFillOnPageLoadOptions: any[];
|
||||
@ -50,7 +55,7 @@ export class AutofillV1Component implements OnInit {
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private domainSettingsService: DomainSettingsService,
|
||||
private autofillService: AutofillService,
|
||||
private configService: ConfigService,
|
||||
private dialogService: DialogService,
|
||||
private autofillSettingsService: AutofillSettingsServiceAbstraction,
|
||||
private messagingService: MessagingService,
|
||||
@ -109,6 +114,20 @@ export class AutofillV1Component implements OnInit {
|
||||
this.autofillSettingsService.inlineMenuVisibility$,
|
||||
);
|
||||
|
||||
this.inlineMenuPositioningImprovementsEnabled = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.InlineMenuPositioningImprovements,
|
||||
);
|
||||
|
||||
this.inlineMenuIsEnabled = this.isInlineMenuEnabled();
|
||||
|
||||
this.showInlineMenuIdentities =
|
||||
this.inlineMenuPositioningImprovementsEnabled &&
|
||||
(await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$));
|
||||
|
||||
this.showInlineMenuCards =
|
||||
this.inlineMenuPositioningImprovementsEnabled &&
|
||||
(await firstValueFrom(this.autofillSettingsService.showInlineMenuCards$));
|
||||
|
||||
this.enableAutoFillOnPageLoad = await firstValueFrom(
|
||||
this.autofillSettingsService.autofillOnPageLoad$,
|
||||
);
|
||||
@ -140,9 +159,18 @@ export class AutofillV1Component implements OnInit {
|
||||
);
|
||||
}
|
||||
|
||||
isInlineMenuEnabled() {
|
||||
return (
|
||||
this.autoFillOverlayVisibility === AutofillOverlayVisibility.OnFieldFocus ||
|
||||
this.autoFillOverlayVisibility === AutofillOverlayVisibility.OnButtonClick
|
||||
);
|
||||
}
|
||||
|
||||
async updateAutoFillOverlayVisibility() {
|
||||
await this.autofillSettingsService.setInlineMenuVisibility(this.autoFillOverlayVisibility);
|
||||
await this.requestPrivacyPermission();
|
||||
|
||||
this.inlineMenuIsEnabled = this.isInlineMenuEnabled();
|
||||
}
|
||||
|
||||
async updateAutoFillOnPageLoad() {
|
||||
@ -298,4 +326,12 @@ export class AutofillV1Component implements OnInit {
|
||||
async updateShowIdentitiesCurrentTab() {
|
||||
await this.vaultSettingsService.setShowIdentitiesCurrentTab(this.showIdentitiesCurrentTab);
|
||||
}
|
||||
|
||||
async updateShowInlineMenuCards() {
|
||||
await this.autofillSettingsService.setShowInlineMenuCards(this.showInlineMenuCards);
|
||||
}
|
||||
|
||||
async updateShowInlineMenuIdentities() {
|
||||
await this.autofillSettingsService.setShowInlineMenuIdentities(this.showInlineMenuIdentities);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,37 @@
|
||||
{{ "showInlineMenuOnFormFieldsDescAlt" | i18n }}
|
||||
</bit-hint>
|
||||
</bit-form-control>
|
||||
<bit-form-control *ngIf="enableInlineMenu" class="tw-pl-5">
|
||||
<bit-form-control
|
||||
*ngIf="inlineMenuPositioningImprovementsEnabled && enableInlineMenu"
|
||||
class="tw-ml-5"
|
||||
>
|
||||
<input
|
||||
bitCheckbox
|
||||
id="show-inline-menu-identities"
|
||||
type="checkbox"
|
||||
(change)="updateShowInlineMenuIdentities()"
|
||||
[(ngModel)]="showInlineMenuIdentities"
|
||||
/>
|
||||
<bit-label for="show-inline-menu-identities">
|
||||
{{ "showInlineMenuIdentitiesLabel" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-control
|
||||
*ngIf="inlineMenuPositioningImprovementsEnabled && enableInlineMenu"
|
||||
class="tw-ml-5"
|
||||
>
|
||||
<input
|
||||
bitCheckbox
|
||||
id="show-inline-menu-cards"
|
||||
type="checkbox"
|
||||
(change)="updateShowInlineMenuCards()"
|
||||
[(ngModel)]="showInlineMenuCards"
|
||||
/>
|
||||
<bit-label for="show-inline-menu-cards">
|
||||
{{ "showInlineMenuCardsLabel" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-control *ngIf="enableInlineMenu" class="tw-ml-5">
|
||||
<input
|
||||
bitCheckbox
|
||||
id="show-autofill-suggestions-on-icon"
|
||||
|
@ -21,10 +21,12 @@ import {
|
||||
DisablePasswordManagerUri,
|
||||
InlineMenuVisibilitySetting,
|
||||
} from "@bitwarden/common/autofill/types";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import {
|
||||
UriMatchStrategy,
|
||||
UriMatchStrategySetting,
|
||||
} from "@bitwarden/common/models/domain/domain-service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
@ -82,6 +84,7 @@ export class AutofillComponent implements OnInit {
|
||||
protected defaultBrowserAutofillDisabled: boolean = false;
|
||||
protected inlineMenuVisibility: InlineMenuVisibilitySetting =
|
||||
AutofillOverlayVisibility.OnFieldFocus;
|
||||
protected inlineMenuPositioningImprovementsEnabled: boolean = false;
|
||||
protected browserClientVendor: BrowserClientVendor = BrowserClientVendors.Unknown;
|
||||
protected disablePasswordManagerURI: DisablePasswordManagerUri =
|
||||
DisablePasswordManagerUris.Unknown;
|
||||
@ -93,6 +96,8 @@ export class AutofillComponent implements OnInit {
|
||||
enableAutofillOnPageLoad: boolean = false;
|
||||
enableInlineMenu: boolean = false;
|
||||
enableInlineMenuOnIconSelect: boolean = false;
|
||||
showInlineMenuIdentities: boolean = true;
|
||||
showInlineMenuCards: boolean = true;
|
||||
autofillOnPageLoadDefault: boolean = false;
|
||||
autofillOnPageLoadOptions: { name: string; value: boolean }[];
|
||||
enableContextMenuItem: boolean = false;
|
||||
@ -114,6 +119,7 @@ export class AutofillComponent implements OnInit {
|
||||
private autofillSettingsService: AutofillSettingsServiceAbstraction,
|
||||
private messagingService: MessagingService,
|
||||
private vaultSettingsService: VaultSettingsService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.autofillOnPageLoadOptions = [
|
||||
{ name: i18nService.t("autoFillOnPageLoadYes"), value: true },
|
||||
@ -151,6 +157,18 @@ export class AutofillComponent implements OnInit {
|
||||
this.autofillSettingsService.inlineMenuVisibility$,
|
||||
);
|
||||
|
||||
this.inlineMenuPositioningImprovementsEnabled = await this.configService.getFeatureFlag(
|
||||
FeatureFlag.InlineMenuPositioningImprovements,
|
||||
);
|
||||
|
||||
this.showInlineMenuIdentities =
|
||||
this.inlineMenuPositioningImprovementsEnabled &&
|
||||
(await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$));
|
||||
|
||||
this.showInlineMenuCards =
|
||||
this.inlineMenuPositioningImprovementsEnabled &&
|
||||
(await firstValueFrom(this.autofillSettingsService.showInlineMenuCards$));
|
||||
|
||||
this.enableInlineMenuOnIconSelect =
|
||||
this.inlineMenuVisibility === AutofillOverlayVisibility.OnButtonClick;
|
||||
|
||||
@ -381,4 +399,12 @@ export class AutofillComponent implements OnInit {
|
||||
async updateShowIdentitiesCurrentTab() {
|
||||
await this.vaultSettingsService.setShowIdentitiesCurrentTab(this.showIdentitiesCurrentTab);
|
||||
}
|
||||
|
||||
async updateShowInlineMenuCards() {
|
||||
await this.autofillSettingsService.setShowInlineMenuCards(this.showInlineMenuCards);
|
||||
}
|
||||
|
||||
async updateShowInlineMenuIdentities() {
|
||||
await this.autofillSettingsService.setShowInlineMenuIdentities(this.showInlineMenuIdentities);
|
||||
}
|
||||
}
|
||||
|
@ -2238,7 +2238,7 @@ describe("AutofillOverlayContentService", () => {
|
||||
it("updates the inlineMenuVisibility property", () => {
|
||||
sendMockExtensionMessage({
|
||||
command: "updateAutofillInlineMenuVisibility",
|
||||
data: { inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick },
|
||||
data: { newSettingValue: AutofillOverlayVisibility.OnButtonClick },
|
||||
});
|
||||
|
||||
expect(autofillOverlayContentService["inlineMenuVisibility"]).toEqual(
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
AUTOFILL_OVERLAY_HANDLE_REPOSITION,
|
||||
AUTOFILL_TRIGGER_FORM_FIELD_SUBMIT,
|
||||
} from "@bitwarden/common/autofill/constants";
|
||||
import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
|
||||
import {
|
||||
@ -51,7 +52,9 @@ import { AutoFillConstants } from "./autofill-constants";
|
||||
|
||||
export class AutofillOverlayContentService implements AutofillOverlayContentServiceInterface {
|
||||
pageDetailsUpdateRequired = false;
|
||||
inlineMenuVisibility: number;
|
||||
inlineMenuVisibility: InlineMenuVisibilitySetting;
|
||||
private showInlineMenuIdentities: boolean;
|
||||
private showInlineMenuCards: boolean;
|
||||
private readonly findTabs = tabbable;
|
||||
private readonly sendExtensionMessage = sendExtensionMessage;
|
||||
private formFieldElements: Map<ElementWithOpId<FormFieldElement>, AutofillField> = new Map();
|
||||
@ -183,6 +186,18 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
autofillFieldData: AutofillField,
|
||||
pageDetails: AutofillPageDetails,
|
||||
) {
|
||||
if (!this.inlineMenuVisibility) {
|
||||
await this.getInlineMenuVisibility();
|
||||
}
|
||||
|
||||
if (this.showInlineMenuCards == null) {
|
||||
await this.getInlineMenuCardsVisibility();
|
||||
}
|
||||
|
||||
if (this.showInlineMenuIdentities == null) {
|
||||
await this.getInlineMenuIdentitiesVisibility();
|
||||
}
|
||||
|
||||
if (
|
||||
this.formFieldElements.has(formFieldElement) ||
|
||||
this.isIgnoredField(autofillFieldData, pageDetails)
|
||||
@ -1019,10 +1034,16 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
const { width, height, top, left } =
|
||||
await this.getMostRecentlyFocusedFieldRects(formFieldElement);
|
||||
const autofillFieldData = this.formFieldElements.get(formFieldElement);
|
||||
|
||||
let accountCreationFieldType = null;
|
||||
|
||||
if (
|
||||
// user setting allows display of identities in inline menu
|
||||
this.showInlineMenuIdentities &&
|
||||
// `showInlineMenuAccountCreation` has been set or field is filled by Login cipher
|
||||
(autofillFieldData?.showInlineMenuAccountCreation ||
|
||||
autofillFieldData?.filledByCipherType === CipherType.Login) &&
|
||||
// field is a username field, which is relevant to both Identity and Login ciphers
|
||||
this.inlineMenuFieldQualificationService.isUsernameField(autofillFieldData)
|
||||
) {
|
||||
accountCreationFieldType = this.inlineMenuFieldQualificationService.isEmailField(
|
||||
@ -1125,6 +1146,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
}
|
||||
|
||||
if (
|
||||
this.showInlineMenuCards &&
|
||||
this.inlineMenuFieldQualificationService.isFieldForCreditCardForm(
|
||||
autofillFieldData,
|
||||
pageDetails,
|
||||
@ -1135,6 +1157,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
}
|
||||
|
||||
if (
|
||||
this.showInlineMenuIdentities &&
|
||||
this.inlineMenuFieldQualificationService.isFieldForAccountCreationForm(
|
||||
autofillFieldData,
|
||||
pageDetails,
|
||||
@ -1146,6 +1169,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
}
|
||||
|
||||
if (
|
||||
this.showInlineMenuIdentities &&
|
||||
this.inlineMenuFieldQualificationService.isFieldForIdentityForm(
|
||||
autofillFieldData,
|
||||
pageDetails,
|
||||
@ -1244,6 +1268,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
autofillFieldData.readonly = getAttributeBoolean(formFieldElement, "disabled");
|
||||
autofillFieldData.disabled = getAttributeBoolean(formFieldElement, "disabled");
|
||||
autofillFieldData.viewable = true;
|
||||
|
||||
void this.setupOverlayListenersOnQualifiedField(formFieldElement, autofillFieldData);
|
||||
}
|
||||
|
||||
@ -1266,10 +1291,6 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
await this.updateMostRecentlyFocusedField(formFieldElement);
|
||||
}
|
||||
|
||||
if (!this.inlineMenuVisibility) {
|
||||
await this.getInlineMenuVisibility();
|
||||
}
|
||||
|
||||
this.setupFormFieldElementEventListeners(formFieldElement);
|
||||
this.setupFormSubmissionEventListeners(formFieldElement, autofillFieldData);
|
||||
|
||||
@ -1291,6 +1312,30 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
this.inlineMenuVisibility = inlineMenuVisibility || AutofillOverlayVisibility.OnFieldFocus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the background script for the autofill inline menu's Cards visibility setting.
|
||||
* If the setting is not found, a default value of true will be used
|
||||
* @private
|
||||
*/
|
||||
private async getInlineMenuCardsVisibility() {
|
||||
const inlineMenuCardsVisibility = await this.sendExtensionMessage(
|
||||
"getInlineMenuCardsVisibility",
|
||||
);
|
||||
this.showInlineMenuCards = inlineMenuCardsVisibility ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the background script for the autofill inline menu's Identities visibility setting.
|
||||
* If the setting is not found, a default value of true will be used
|
||||
* @private
|
||||
*/
|
||||
private async getInlineMenuIdentitiesVisibility() {
|
||||
const inlineMenuIdentitiesVisibility = await this.sendExtensionMessage(
|
||||
"getInlineMenuIdentitiesVisibility",
|
||||
);
|
||||
this.showInlineMenuIdentities = inlineMenuIdentitiesVisibility ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value that indicates if we should hide the inline menu list due to a filled field.
|
||||
*
|
||||
@ -1318,8 +1363,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
||||
* @param data - The data object from the extension message.
|
||||
*/
|
||||
private updateInlineMenuVisibility({ data }: AutofillExtensionMessage) {
|
||||
if (!isNaN(data?.inlineMenuVisibility)) {
|
||||
this.inlineMenuVisibility = data.inlineMenuVisibility;
|
||||
const newSettingValue = data?.newSettingValue;
|
||||
|
||||
if (!isNaN(newSettingValue)) {
|
||||
this.inlineMenuVisibility = newSettingValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,8 @@ describe("AutofillService", () => {
|
||||
let autofillService: AutofillService;
|
||||
const cipherService = mock<CipherService>();
|
||||
let inlineMenuVisibilityMock$!: BehaviorSubject<InlineMenuVisibilitySetting>;
|
||||
let showInlineMenuCardsMock$!: BehaviorSubject<boolean>;
|
||||
let showInlineMenuIdentitiesMock$!: BehaviorSubject<boolean>;
|
||||
let autofillSettingsService: MockProxy<AutofillSettingsServiceAbstraction>;
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
const accountService: FakeAccountService = mockAccountServiceWith(mockUserId);
|
||||
@ -98,8 +100,12 @@ describe("AutofillService", () => {
|
||||
beforeEach(() => {
|
||||
scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService);
|
||||
inlineMenuVisibilityMock$ = new BehaviorSubject(AutofillOverlayVisibility.OnFieldFocus);
|
||||
showInlineMenuCardsMock$ = new BehaviorSubject(false);
|
||||
showInlineMenuIdentitiesMock$ = new BehaviorSubject(false);
|
||||
autofillSettingsService = mock<AutofillSettingsServiceAbstraction>();
|
||||
autofillSettingsService.inlineMenuVisibility$ = inlineMenuVisibilityMock$;
|
||||
autofillSettingsService.showInlineMenuCards$ = showInlineMenuCardsMock$;
|
||||
autofillSettingsService.showInlineMenuIdentities$ = showInlineMenuIdentitiesMock$;
|
||||
activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked);
|
||||
authService = mock<AuthService>();
|
||||
authService.activeAccountStatus$ = activeAccountStatusMock$;
|
||||
@ -291,12 +297,12 @@ describe("AutofillService", () => {
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
tab1,
|
||||
"updateAutofillInlineMenuVisibility",
|
||||
{ inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick },
|
||||
{ newSettingValue: AutofillOverlayVisibility.OnButtonClick },
|
||||
);
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
tab2,
|
||||
"updateAutofillInlineMenuVisibility",
|
||||
{ inlineMenuVisibility: AutofillOverlayVisibility.OnButtonClick },
|
||||
{ newSettingValue: AutofillOverlayVisibility.OnButtonClick },
|
||||
);
|
||||
});
|
||||
|
||||
@ -308,12 +314,12 @@ describe("AutofillService", () => {
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
tab1,
|
||||
"updateAutofillInlineMenuVisibility",
|
||||
{ inlineMenuVisibility: AutofillOverlayVisibility.OnFieldFocus },
|
||||
{ newSettingValue: AutofillOverlayVisibility.OnFieldFocus },
|
||||
);
|
||||
expect(BrowserApi.tabSendMessageData).toHaveBeenCalledWith(
|
||||
tab2,
|
||||
"updateAutofillInlineMenuVisibility",
|
||||
{ inlineMenuVisibility: AutofillOverlayVisibility.OnFieldFocus },
|
||||
{ newSettingValue: AutofillOverlayVisibility.OnFieldFocus },
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -130,10 +130,23 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
async loadAutofillScriptsOnInstall() {
|
||||
BrowserApi.addListener(chrome.runtime.onConnect, this.handleInjectedScriptPortConnection);
|
||||
void this.injectAutofillScriptsInAllTabs();
|
||||
|
||||
this.autofillSettingsService.inlineMenuVisibility$
|
||||
.pipe(startWith(undefined), pairwise())
|
||||
.subscribe(([previousSetting, currentSetting]) =>
|
||||
this.handleInlineMenuVisibilityChange(previousSetting, currentSetting),
|
||||
this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting),
|
||||
);
|
||||
|
||||
this.autofillSettingsService.showInlineMenuCards$
|
||||
.pipe(startWith(undefined), pairwise())
|
||||
.subscribe(([previousSetting, currentSetting]) =>
|
||||
this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting),
|
||||
);
|
||||
|
||||
this.autofillSettingsService.showInlineMenuIdentities$
|
||||
.pipe(startWith(undefined), pairwise())
|
||||
.subscribe(([previousSetting, currentSetting]) =>
|
||||
this.handleInlineMenuVisibilitySettingsChange(previousSetting, currentSetting),
|
||||
);
|
||||
}
|
||||
|
||||
@ -3043,27 +3056,36 @@ export default class AutofillService implements AutofillServiceInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the autofill inline menu visibility setting in all active tabs
|
||||
* when the InlineMenuVisibilitySetting observable is updated.
|
||||
* Updates the autofill inline menu visibility settings in all active tabs
|
||||
* when the inlineMenuVisibility, showInlineMenuCards, or showInlineMenuIdentities
|
||||
* observables are updated.
|
||||
*
|
||||
* @param previousSetting - The previous setting value
|
||||
* @param currentSetting - The current setting value
|
||||
* @param oldSettingValue - The previous setting value
|
||||
* @param newSettingValue - The current setting value
|
||||
* @param cipherType - The cipher type of the changed inline menu setting
|
||||
*/
|
||||
private async handleInlineMenuVisibilityChange(
|
||||
previousSetting: InlineMenuVisibilitySetting,
|
||||
currentSetting: InlineMenuVisibilitySetting,
|
||||
private async handleInlineMenuVisibilitySettingsChange(
|
||||
oldSettingValue: InlineMenuVisibilitySetting | boolean,
|
||||
newSettingValue: InlineMenuVisibilitySetting | boolean,
|
||||
) {
|
||||
if (previousSetting === undefined || previousSetting === currentSetting) {
|
||||
if (oldSettingValue === undefined || oldSettingValue === newSettingValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inlineMenuPreviouslyDisabled = previousSetting === AutofillOverlayVisibility.Off;
|
||||
const inlineMenuCurrentlyDisabled = currentSetting === AutofillOverlayVisibility.Off;
|
||||
if (!inlineMenuPreviouslyDisabled && !inlineMenuCurrentlyDisabled) {
|
||||
const isInlineMenuVisibilitySubSetting =
|
||||
typeof oldSettingValue === "boolean" || typeof newSettingValue === "boolean";
|
||||
const inlineMenuPreviouslyDisabled = oldSettingValue === AutofillOverlayVisibility.Off;
|
||||
const inlineMenuCurrentlyDisabled = newSettingValue === AutofillOverlayVisibility.Off;
|
||||
|
||||
if (
|
||||
!isInlineMenuVisibilitySubSetting &&
|
||||
!inlineMenuPreviouslyDisabled &&
|
||||
!inlineMenuCurrentlyDisabled
|
||||
) {
|
||||
const tabs = await BrowserApi.tabsQuery({});
|
||||
tabs.forEach((tab) =>
|
||||
BrowserApi.tabSendMessageData(tab, "updateAutofillInlineMenuVisibility", {
|
||||
inlineMenuVisibility: currentSetting,
|
||||
newSettingValue,
|
||||
}),
|
||||
);
|
||||
return;
|
||||
|
@ -59,6 +59,24 @@ const INLINE_MENU_VISIBILITY = new KeyDefinition(
|
||||
},
|
||||
);
|
||||
|
||||
const SHOW_INLINE_MENU_IDENTITIES = new UserKeyDefinition(
|
||||
AUTOFILL_SETTINGS_DISK,
|
||||
"showInlineMenuIdentities",
|
||||
{
|
||||
deserializer: (value: boolean) => value ?? true,
|
||||
clearOn: [],
|
||||
},
|
||||
);
|
||||
|
||||
const SHOW_INLINE_MENU_CARDS = new UserKeyDefinition(
|
||||
AUTOFILL_SETTINGS_DISK,
|
||||
"showInlineMenuCards",
|
||||
{
|
||||
deserializer: (value: boolean) => value ?? true,
|
||||
clearOn: [],
|
||||
},
|
||||
);
|
||||
|
||||
const ENABLE_CONTEXT_MENU = new KeyDefinition(AUTOFILL_SETTINGS_DISK, "enableContextMenu", {
|
||||
deserializer: (value: boolean) => value ?? true,
|
||||
});
|
||||
@ -86,6 +104,10 @@ export abstract class AutofillSettingsServiceAbstraction {
|
||||
setAutoCopyTotp: (newValue: boolean) => Promise<void>;
|
||||
inlineMenuVisibility$: Observable<InlineMenuVisibilitySetting>;
|
||||
setInlineMenuVisibility: (newValue: InlineMenuVisibilitySetting) => Promise<void>;
|
||||
showInlineMenuIdentities$: Observable<boolean>;
|
||||
setShowInlineMenuIdentities: (newValue: boolean) => Promise<void>;
|
||||
showInlineMenuCards$: Observable<boolean>;
|
||||
setShowInlineMenuCards: (newValue: boolean) => Promise<void>;
|
||||
enableContextMenu$: Observable<boolean>;
|
||||
setEnableContextMenu: (newValue: boolean) => Promise<void>;
|
||||
clearClipboardDelay$: Observable<ClearClipboardDelaySetting>;
|
||||
@ -113,6 +135,12 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti
|
||||
private inlineMenuVisibilityState: GlobalState<InlineMenuVisibilitySetting>;
|
||||
readonly inlineMenuVisibility$: Observable<InlineMenuVisibilitySetting>;
|
||||
|
||||
private showInlineMenuIdentitiesState: ActiveUserState<boolean>;
|
||||
readonly showInlineMenuIdentities$: Observable<boolean>;
|
||||
|
||||
private showInlineMenuCardsState: ActiveUserState<boolean>;
|
||||
readonly showInlineMenuCards$: Observable<boolean>;
|
||||
|
||||
private enableContextMenuState: GlobalState<boolean>;
|
||||
readonly enableContextMenu$: Observable<boolean>;
|
||||
|
||||
@ -157,6 +185,14 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti
|
||||
map((x) => x ?? AutofillOverlayVisibility.Off),
|
||||
);
|
||||
|
||||
this.showInlineMenuIdentitiesState = this.stateProvider.getActive(SHOW_INLINE_MENU_IDENTITIES);
|
||||
this.showInlineMenuIdentities$ = this.showInlineMenuIdentitiesState.state$.pipe(
|
||||
map((x) => x ?? true),
|
||||
);
|
||||
|
||||
this.showInlineMenuCardsState = this.stateProvider.getActive(SHOW_INLINE_MENU_CARDS);
|
||||
this.showInlineMenuCards$ = this.showInlineMenuCardsState.state$.pipe(map((x) => x ?? true));
|
||||
|
||||
this.enableContextMenuState = this.stateProvider.getGlobal(ENABLE_CONTEXT_MENU);
|
||||
this.enableContextMenu$ = this.enableContextMenuState.state$.pipe(map((x) => x ?? true));
|
||||
|
||||
@ -190,6 +226,14 @@ export class AutofillSettingsService implements AutofillSettingsServiceAbstracti
|
||||
await this.inlineMenuVisibilityState.update(() => newValue);
|
||||
}
|
||||
|
||||
async setShowInlineMenuIdentities(newValue: boolean): Promise<void> {
|
||||
await this.showInlineMenuIdentitiesState.update(() => newValue);
|
||||
}
|
||||
|
||||
async setShowInlineMenuCards(newValue: boolean): Promise<void> {
|
||||
await this.showInlineMenuCardsState.update(() => newValue);
|
||||
}
|
||||
|
||||
async setEnableContextMenu(newValue: boolean): Promise<void> {
|
||||
await this.enableContextMenuState.update(() => newValue);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user