[PM-10138] Inline menu not properly validating as the top-most element within mutation observer (#10292)
* [PM-10138] Inline menu not properly validating as the top-most element within mutation observer * [PM-10138] Identity inline menu appearing for invalid field types * [PM-10138] Identity inline menu appearing for invalid field types * [PM-10138] Fixing an issue present with references to card and identity ciphers * [PM-10138] Fixing issues with initialization of the inline menu * [PM-10138] Fixing issues with initialization of the inline menu * [PM-10138] Removing inclusion of file protocol when injecting scripts
This commit is contained in:
parent
ea362a9ed9
commit
85c8ff04a1
|
@ -190,7 +190,6 @@ export type OverlayBackgroundExtensionMessageHandlers = {
|
||||||
}: BackgroundOnMessageHandlerParams) => void;
|
}: BackgroundOnMessageHandlerParams) => void;
|
||||||
collectPageDetailsResponse: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
|
collectPageDetailsResponse: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
|
||||||
unlockCompleted: ({ message }: BackgroundMessageParam) => void;
|
unlockCompleted: ({ message }: BackgroundMessageParam) => void;
|
||||||
doFullSync: () => void;
|
|
||||||
addedCipher: () => void;
|
addedCipher: () => void;
|
||||||
addEditCipherSubmitted: () => void;
|
addEditCipherSubmitted: () => void;
|
||||||
editedCipher: () => void;
|
editedCipher: () => void;
|
||||||
|
|
|
@ -2014,7 +2014,6 @@ describe("OverlayBackground", () => {
|
||||||
|
|
||||||
describe("extension messages that trigger an update of the inline menu ciphers", () => {
|
describe("extension messages that trigger an update of the inline menu ciphers", () => {
|
||||||
const extensionMessages = [
|
const extensionMessages = [
|
||||||
"doFullSync",
|
|
||||||
"addedCipher",
|
"addedCipher",
|
||||||
"addEditCipherSubmitted",
|
"addEditCipherSubmitted",
|
||||||
"editedCipher",
|
"editedCipher",
|
||||||
|
|
|
@ -120,7 +120,6 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
this.triggerDestroyInlineMenuListeners(sender.tab, message.subFrameData.frameId),
|
this.triggerDestroyInlineMenuListeners(sender.tab, message.subFrameData.frameId),
|
||||||
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
|
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
|
||||||
unlockCompleted: ({ message }) => this.unlockCompleted(message),
|
unlockCompleted: ({ message }) => this.unlockCompleted(message),
|
||||||
doFullSync: () => this.updateOverlayCiphers(),
|
|
||||||
addedCipher: () => this.updateOverlayCiphers(),
|
addedCipher: () => this.updateOverlayCiphers(),
|
||||||
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
|
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
|
||||||
editedCipher: () => this.updateOverlayCiphers(),
|
editedCipher: () => this.updateOverlayCiphers(),
|
||||||
|
@ -273,7 +272,9 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
||||||
await this.cipherService.getAllDecryptedForUrl(currentTab?.url || "")
|
await this.cipherService.getAllDecryptedForUrl(currentTab?.url || "")
|
||||||
).sort((a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b));
|
).sort((a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b));
|
||||||
|
|
||||||
return cipherViews.concat(...this.cardAndIdentityCiphers);
|
return this.cardAndIdentityCiphers
|
||||||
|
? cipherViews.concat(...this.cardAndIdentityCiphers)
|
||||||
|
: cipherViews;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -399,6 +399,11 @@ describe("AutofillInlineMenuContentService", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets the z-index of to a lower value", async () => {
|
it("sets the z-index of to a lower value", async () => {
|
||||||
|
autofillInlineMenuContentService["handlePersistentLastChildOverrideTimeout"] = setTimeout(
|
||||||
|
jest.fn(),
|
||||||
|
1000,
|
||||||
|
);
|
||||||
|
|
||||||
await autofillInlineMenuContentService["handleBodyElementMutationObserverUpdate"]();
|
await autofillInlineMenuContentService["handleBodyElementMutationObserverUpdate"]();
|
||||||
await waitForIdleCallback();
|
await waitForIdleCallback();
|
||||||
|
|
||||||
|
@ -411,8 +416,9 @@ describe("AutofillInlineMenuContentService", () => {
|
||||||
});
|
});
|
||||||
globalThis.document.elementFromPoint = jest.fn(() => persistentLastChild);
|
globalThis.document.elementFromPoint = jest.fn(() => persistentLastChild);
|
||||||
|
|
||||||
await autofillInlineMenuContentService["handleBodyElementMutationObserverUpdate"]();
|
await autofillInlineMenuContentService["verifyInlineMenuIsNotObscured"](
|
||||||
await waitForIdleCallback();
|
persistentLastChild,
|
||||||
|
);
|
||||||
|
|
||||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("autofillOverlayElementClosed", {
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("autofillOverlayElementClosed", {
|
||||||
overlayElement: AutofillOverlayElement.Button,
|
overlayElement: AutofillOverlayElement.Button,
|
||||||
|
@ -425,8 +431,9 @@ describe("AutofillInlineMenuContentService", () => {
|
||||||
});
|
});
|
||||||
globalThis.document.elementFromPoint = jest.fn(() => persistentLastChild);
|
globalThis.document.elementFromPoint = jest.fn(() => persistentLastChild);
|
||||||
|
|
||||||
await autofillInlineMenuContentService["handleBodyElementMutationObserverUpdate"]();
|
await autofillInlineMenuContentService["verifyInlineMenuIsNotObscured"](
|
||||||
await waitForIdleCallback();
|
persistentLastChild,
|
||||||
|
);
|
||||||
|
|
||||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("autofillOverlayElementClosed", {
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("autofillOverlayElementClosed", {
|
||||||
overlayElement: AutofillOverlayElement.List,
|
overlayElement: AutofillOverlayElement.List,
|
||||||
|
|
|
@ -33,6 +33,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
private bodyElementMutationObserver: MutationObserver;
|
private bodyElementMutationObserver: MutationObserver;
|
||||||
private mutationObserverIterations = 0;
|
private mutationObserverIterations = 0;
|
||||||
private mutationObserverIterationsResetTimeout: number | NodeJS.Timeout;
|
private mutationObserverIterationsResetTimeout: number | NodeJS.Timeout;
|
||||||
|
private handlePersistentLastChildOverrideTimeout: number | NodeJS.Timeout;
|
||||||
private lastElementOverrides: WeakMap<Element, number> = new WeakMap();
|
private lastElementOverrides: WeakMap<Element, number> = new WeakMap();
|
||||||
private readonly customElementDefaultStyles: Partial<CSSStyleDeclaration> = {
|
private readonly customElementDefaultStyles: Partial<CSSStyleDeclaration> = {
|
||||||
all: "initial",
|
all: "initial",
|
||||||
|
@ -405,7 +406,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.lastElementOverrides.get(lastChild) >= 3) {
|
if (this.lastElementOverrides.get(lastChild) >= 3) {
|
||||||
await this.handlePersistentLastChildOverride(lastChild);
|
this.handlePersistentLastChildOverride(lastChild);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -430,6 +431,26 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
globalThis.document.body.insertBefore(lastChild, this.buttonElement);
|
globalThis.document.body.insertBefore(lastChild, this.buttonElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the behavior of a persistent child element that is forcing itself to
|
||||||
|
* the bottom of the body element. This method will ensure that the inline menu
|
||||||
|
* elements are not obscured by the persistent child element.
|
||||||
|
*
|
||||||
|
* @param lastChild - The last child of the body element.
|
||||||
|
*/
|
||||||
|
private handlePersistentLastChildOverride(lastChild: Element) {
|
||||||
|
const lastChildZIndex = parseInt((lastChild as HTMLElement).style.zIndex);
|
||||||
|
if (lastChildZIndex >= 2147483647) {
|
||||||
|
(lastChild as HTMLElement).style.zIndex = "2147483646";
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clearPersistentLastChildOverrideTimeout();
|
||||||
|
this.handlePersistentLastChildOverrideTimeout = globalThis.setTimeout(
|
||||||
|
() => this.verifyInlineMenuIsNotObscured(lastChild),
|
||||||
|
500,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies if the last child of the body element is overlaying the inline menu elements.
|
* Verifies if the last child of the body element is overlaying the inline menu elements.
|
||||||
* This is triggered when the last child of the body is being forced by some script to
|
* This is triggered when the last child of the body is being forced by some script to
|
||||||
|
@ -437,12 +458,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
*
|
*
|
||||||
* @param lastChild - The last child of the body element.
|
* @param lastChild - The last child of the body element.
|
||||||
*/
|
*/
|
||||||
private async handlePersistentLastChildOverride(lastChild: Element) {
|
private verifyInlineMenuIsNotObscured = async (lastChild: Element) => {
|
||||||
const lastChildZIndex = parseInt((lastChild as HTMLElement).style.zIndex);
|
|
||||||
if (lastChildZIndex >= 2147483647) {
|
|
||||||
(lastChild as HTMLElement).style.zIndex = "2147483646";
|
|
||||||
}
|
|
||||||
|
|
||||||
const inlineMenuPosition: InlineMenuPosition = await this.sendExtensionMessage(
|
const inlineMenuPosition: InlineMenuPosition = await this.sendExtensionMessage(
|
||||||
"getAutofillInlineMenuPosition",
|
"getAutofillInlineMenuPosition",
|
||||||
);
|
);
|
||||||
|
@ -456,7 +472,7 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
if (!!list && this.elementAtCenterOfInlineMenuPosition(list) === lastChild) {
|
if (!!list && this.elementAtCenterOfInlineMenuPosition(list) === lastChild) {
|
||||||
this.closeInlineMenu();
|
this.closeInlineMenu();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the element present at the center of the inline menu position.
|
* Returns the element present at the center of the inline menu position.
|
||||||
|
@ -470,6 +486,16 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the timeout that is used to verify that the last child of the body element
|
||||||
|
* is not overlaying the inline menu elements.
|
||||||
|
*/
|
||||||
|
private clearPersistentLastChildOverrideTimeout() {
|
||||||
|
if (this.handlePersistentLastChildOverrideTimeout) {
|
||||||
|
globalThis.clearTimeout(this.handlePersistentLastChildOverrideTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies if the mutation observer is triggering excessive iterations.
|
* Identifies if the mutation observer is triggering excessive iterations.
|
||||||
* Will trigger a blur of the most recently focused field and remove the
|
* Will trigger a blur of the most recently focused field and remove the
|
||||||
|
@ -503,5 +529,6 @@ export class AutofillInlineMenuContentService implements AutofillInlineMenuConte
|
||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
this.closeInlineMenu();
|
this.closeInlineMenu();
|
||||||
|
this.clearPersistentLastChildOverrideTimeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -377,6 +377,21 @@ describe("AutofillInlineMenuIframeService", () => {
|
||||||
autofillInlineMenuIframeService["ariaAlertElement"],
|
autofillInlineMenuIframeService["ariaAlertElement"],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("resets the fade in timeout if it is set", () => {
|
||||||
|
autofillInlineMenuIframeService["fadeInTimeout"] = setTimeout(jest.fn, 100);
|
||||||
|
const styles = { top: "100px", left: "100px" };
|
||||||
|
jest.spyOn(autofillInlineMenuIframeService as any, "handleFadeInInlineMenuIframe");
|
||||||
|
|
||||||
|
sendPortMessage(portSpy, {
|
||||||
|
command: "updateAutofillInlineMenuPosition",
|
||||||
|
styles,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
autofillInlineMenuIframeService["handleFadeInInlineMenuIframe"],
|
||||||
|
).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("updates the visibility of the iframe", () => {
|
it("updates the visibility of the iframe", () => {
|
||||||
|
|
|
@ -260,10 +260,13 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const styles = this.fadeInTimeout ? Object.assign(position, { opacity: "0" }) : position;
|
||||||
|
this.updateElementStyles(this.iframe, styles);
|
||||||
|
|
||||||
if (this.fadeInTimeout) {
|
if (this.fadeInTimeout) {
|
||||||
this.handleFadeInInlineMenuIframe();
|
this.handleFadeInInlineMenuIframe();
|
||||||
}
|
}
|
||||||
this.updateElementStyles(this.iframe, position);
|
|
||||||
this.announceAriaAlert();
|
this.announceAriaAlert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,10 +323,10 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
|
||||||
*/
|
*/
|
||||||
private handleFadeInInlineMenuIframe() {
|
private handleFadeInInlineMenuIframe() {
|
||||||
this.clearFadeInTimeout();
|
this.clearFadeInTimeout();
|
||||||
this.fadeInTimeout = globalThis.setTimeout(
|
this.fadeInTimeout = globalThis.setTimeout(() => {
|
||||||
() => this.updateElementStyles(this.iframe, { display: "block", opacity: "1" }),
|
this.updateElementStyles(this.iframe, { display: "block", opacity: "1" });
|
||||||
10,
|
this.clearFadeInTimeout();
|
||||||
);
|
}, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,7 @@ export class InlineMenuFieldQualificationService
|
||||||
implements InlineMenuFieldQualificationServiceInterface
|
implements InlineMenuFieldQualificationServiceInterface
|
||||||
{
|
{
|
||||||
private searchFieldNamesSet = new Set(AutoFillConstants.SearchFieldNames);
|
private searchFieldNamesSet = new Set(AutoFillConstants.SearchFieldNames);
|
||||||
private excludedAutofillLoginTypesSet = new Set(AutoFillConstants.ExcludedAutofillLoginTypes);
|
private excludedAutofillFieldTypesSet = new Set(AutoFillConstants.ExcludedAutofillLoginTypes);
|
||||||
private usernameFieldTypes = new Set(["text", "email", "number", "tel"]);
|
private usernameFieldTypes = new Set(["text", "email", "number", "tel"]);
|
||||||
private usernameAutocompleteValue = "username";
|
private usernameAutocompleteValue = "username";
|
||||||
private emailAutocompleteValue = "email";
|
private emailAutocompleteValue = "email";
|
||||||
|
@ -244,6 +244,10 @@ export class InlineMenuFieldQualificationService
|
||||||
* @param pageDetails - The details of the page that the field is on.
|
* @param pageDetails - The details of the page that the field is on.
|
||||||
*/
|
*/
|
||||||
isFieldForAccountCreationForm(field: AutofillField, pageDetails: AutofillPageDetails): boolean {
|
isFieldForAccountCreationForm(field: AutofillField, pageDetails: AutofillPageDetails): boolean {
|
||||||
|
if (this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.isUsernameField(field) && !this.isPasswordField(field)) {
|
if (!this.isUsernameField(field) && !this.isPasswordField(field)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -286,6 +290,10 @@ export class InlineMenuFieldQualificationService
|
||||||
* @param _pageDetails - Currently unused, will likely be required in the future
|
* @param _pageDetails - Currently unused, will likely be required in the future
|
||||||
*/
|
*/
|
||||||
isFieldForIdentityForm(field: AutofillField, _pageDetails: AutofillPageDetails): boolean {
|
isFieldForIdentityForm(field: AutofillField, _pageDetails: AutofillPageDetails): boolean {
|
||||||
|
if (this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.fieldContainsAutocompleteValues(field, this.identityAutocompleteValues)) {
|
if (this.fieldContainsAutocompleteValues(field, this.identityAutocompleteValues)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -833,7 +841,7 @@ export class InlineMenuFieldQualificationService
|
||||||
isUsernameField = (field: AutofillField): boolean => {
|
isUsernameField = (field: AutofillField): boolean => {
|
||||||
if (
|
if (
|
||||||
!this.usernameFieldTypes.has(field.type) ||
|
!this.usernameFieldTypes.has(field.type) ||
|
||||||
this.isExcludedFieldType(field, this.excludedAutofillLoginTypesSet)
|
this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -852,7 +860,7 @@ export class InlineMenuFieldQualificationService
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!this.isExcludedFieldType(field, this.excludedAutofillLoginTypesSet) &&
|
!this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet) &&
|
||||||
this.keywordsFoundInFieldData(field, AutoFillConstants.EmailFieldNames)
|
this.keywordsFoundInFieldData(field, AutoFillConstants.EmailFieldNames)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -898,7 +906,7 @@ export class InlineMenuFieldQualificationService
|
||||||
const isInputPasswordType = field.type === "password";
|
const isInputPasswordType = field.type === "password";
|
||||||
if (
|
if (
|
||||||
(!isInputPasswordType &&
|
(!isInputPasswordType &&
|
||||||
this.isExcludedFieldType(field, this.excludedAutofillLoginTypesSet)) ||
|
this.isExcludedFieldType(field, this.excludedAutofillFieldTypesSet)) ||
|
||||||
this.fieldHasDisqualifyingAttributeValue(field)
|
this.fieldHasDisqualifyingAttributeValue(field)
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1245,6 +1245,13 @@ export default class MainBackground {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateOverlayCiphers() {
|
||||||
|
// overlayBackground null in popup only contexts
|
||||||
|
if (this.overlayBackground) {
|
||||||
|
await this.overlayBackground.updateOverlayCiphers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch accounts to indicated userId -- null is no active user
|
* Switch accounts to indicated userId -- null is no active user
|
||||||
*/
|
*/
|
||||||
|
@ -1273,7 +1280,7 @@ export default class MainBackground {
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
await this.refreshBadge();
|
await this.refreshBadge();
|
||||||
await this.refreshMenu();
|
await this.refreshMenu();
|
||||||
await this.overlayBackground?.updateOverlayCiphers(); // null in popup only contexts
|
await this.updateOverlayCiphers();
|
||||||
this.messagingService.send("goHome");
|
this.messagingService.send("goHome");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1303,7 @@ export default class MainBackground {
|
||||||
this.messagingService.send("unlocked", { userId: userId });
|
this.messagingService.send("unlocked", { userId: userId });
|
||||||
await this.refreshBadge();
|
await this.refreshBadge();
|
||||||
await this.refreshMenu();
|
await this.refreshMenu();
|
||||||
await this.overlayBackground?.updateOverlayCiphers(); // null in popup only contexts
|
await this.updateOverlayCiphers();
|
||||||
await this.syncService.fullSync(false);
|
await this.syncService.fullSync(false);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1480,7 +1487,17 @@ export default class MainBackground {
|
||||||
* Temporary solution to handle initialization of the overlay background behind a feature flag.
|
* Temporary solution to handle initialization of the overlay background behind a feature flag.
|
||||||
* Will be reverted to instantiation within the constructor once the feature flag is removed.
|
* Will be reverted to instantiation within the constructor once the feature flag is removed.
|
||||||
*/
|
*/
|
||||||
private async initOverlayAndTabsBackground() {
|
async initOverlayAndTabsBackground() {
|
||||||
|
if (
|
||||||
|
this.popupOnlyContext ||
|
||||||
|
this.overlayBackground ||
|
||||||
|
this.tabsBackground ||
|
||||||
|
(await firstValueFrom(this.authService.activeAccountStatus$)) ===
|
||||||
|
AuthenticationStatus.LoggedOut
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const inlineMenuPositioningImprovementsEnabled = await this.configService.getFeatureFlag(
|
const inlineMenuPositioningImprovementsEnabled = await this.configService.getFeatureFlag(
|
||||||
FeatureFlag.InlineMenuPositioningImprovements,
|
FeatureFlag.InlineMenuPositioningImprovements,
|
||||||
);
|
);
|
||||||
|
|
|
@ -200,6 +200,7 @@ export default class RuntimeBackground {
|
||||||
let item: LockedVaultPendingNotificationsData;
|
let item: LockedVaultPendingNotificationsData;
|
||||||
|
|
||||||
if (msg.command === "loggedIn") {
|
if (msg.command === "loggedIn") {
|
||||||
|
await this.main.initOverlayAndTabsBackground();
|
||||||
await this.sendBwInstalledMessageToVault();
|
await this.sendBwInstalledMessageToVault();
|
||||||
await this.autofillService.reloadAutofillScripts();
|
await this.autofillService.reloadAutofillScripts();
|
||||||
}
|
}
|
||||||
|
@ -246,6 +247,7 @@ export default class RuntimeBackground {
|
||||||
await this.main.refreshMenu();
|
await this.main.refreshMenu();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
await this.configService.ensureConfigFetched();
|
await this.configService.ensureConfigFetched();
|
||||||
|
await this.main.updateOverlayCiphers();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "openPopup":
|
case "openPopup":
|
||||||
|
|
Loading…
Reference in New Issue