mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
[PM-5878] Rework window
call within OverlayBackground to function within AutofillOverlayIframe service (#7770)
This commit is contained in:
parent
c26f1fbf0e
commit
52c8cab152
@ -1028,12 +1028,13 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
it("gets the system theme", async () => {
|
it("gets the system theme", async () => {
|
||||||
jest.spyOn(overlayBackground["stateService"], "getTheme").mockResolvedValue(ThemeType.System);
|
jest.spyOn(overlayBackground["stateService"], "getTheme").mockResolvedValue(ThemeType.System);
|
||||||
window.matchMedia = jest.fn(() => mock<MediaQueryList>({ matches: true }));
|
|
||||||
|
|
||||||
initOverlayElementPorts({ initList: true, initButton: false });
|
initOverlayElementPorts({ initList: true, initButton: false });
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)");
|
expect(listPortSpy.postMessage).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({ theme: ThemeType.System }),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi
|
|||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
|
||||||
import { ThemeType } from "@bitwarden/common/platform/enums";
|
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||||
@ -482,21 +481,6 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
return this.userAuthStatus;
|
return this.userAuthStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently set theme for the user.
|
|
||||||
*/
|
|
||||||
private async getCurrentTheme() {
|
|
||||||
const theme = await this.stateService.getTheme();
|
|
||||||
|
|
||||||
if (theme !== ThemeType.System) {
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
|
|
||||||
return window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
||||||
? ThemeType.Dark
|
|
||||||
: ThemeType.Light;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a message to the overlay button to update its authentication status.
|
* Sends a message to the overlay button to update its authentication status.
|
||||||
*/
|
*/
|
||||||
@ -744,7 +728,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
command: `initAutofillOverlay${isOverlayListPort ? "List" : "Button"}`,
|
command: `initAutofillOverlay${isOverlayListPort ? "List" : "Button"}`,
|
||||||
authStatus: await this.getAuthStatus(),
|
authStatus: await this.getAuthStatus(),
|
||||||
styleSheetUrl: chrome.runtime.getURL(`overlay/${isOverlayListPort ? "list" : "button"}.css`),
|
styleSheetUrl: chrome.runtime.getURL(`overlay/${isOverlayListPort ? "list" : "button"}.css`),
|
||||||
theme: `theme_${await this.getCurrentTheme()}`,
|
theme: await this.stateService.getTheme(),
|
||||||
translations: this.getTranslations(),
|
translations: this.getTranslations(),
|
||||||
ciphers: isOverlayListPort ? this.getOverlayCipherData() : null,
|
ciphers: isOverlayListPort ? this.getOverlayCipherData() : null,
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
|
import { ThemeType } from "@bitwarden/common/platform/enums";
|
||||||
import { UriMatchType, CipherType } from "@bitwarden/common/vault/enums";
|
import { UriMatchType, CipherType } from "@bitwarden/common/vault/enums";
|
||||||
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
|
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
@ -199,7 +200,7 @@ function createInitAutofillOverlayListMessageMock(
|
|||||||
command: "initAutofillOverlayList",
|
command: "initAutofillOverlayList",
|
||||||
translations: overlayPagesTranslations,
|
translations: overlayPagesTranslations,
|
||||||
styleSheetUrl: "https://jest-testing-website.com",
|
styleSheetUrl: "https://jest-testing-website.com",
|
||||||
theme: "light",
|
theme: ThemeType.Light,
|
||||||
authStatus: AuthenticationStatus.Unlocked,
|
authStatus: AuthenticationStatus.Unlocked,
|
||||||
ciphers: [
|
ciphers: [
|
||||||
createAutofillOverlayCipherDataMock(1, {
|
createAutofillOverlayCipherDataMock(1, {
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import { mock } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { ThemeType } from "@bitwarden/common/platform/enums";
|
||||||
|
|
||||||
import { EVENTS } from "../../constants";
|
import { EVENTS } from "../../constants";
|
||||||
import { createPortSpyMock } from "../../jest/autofill-mocks";
|
import { createPortSpyMock } from "../../jest/autofill-mocks";
|
||||||
import {
|
import {
|
||||||
@ -208,10 +212,10 @@ describe("AutofillOverlayIframeService", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("passed the message on to the iframe element", () => {
|
it("passes the message on to the iframe element", () => {
|
||||||
const message = {
|
const message = {
|
||||||
command: "initAutofillOverlayList",
|
command: "initAutofillOverlayList",
|
||||||
theme: "theme_light",
|
theme: ThemeType.Light,
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPortMessage(portSpy, message);
|
sendPortMessage(portSpy, message);
|
||||||
@ -223,10 +227,48 @@ describe("AutofillOverlayIframeService", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sets a light theme based on the user's system preferences", () => {
|
||||||
|
window.matchMedia = jest.fn(() => mock<MediaQueryList>({ matches: false }));
|
||||||
|
const message = {
|
||||||
|
command: "initAutofillOverlayList",
|
||||||
|
theme: ThemeType.System,
|
||||||
|
};
|
||||||
|
|
||||||
|
sendPortMessage(portSpy, message);
|
||||||
|
|
||||||
|
expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)");
|
||||||
|
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
|
||||||
|
{
|
||||||
|
command: "initAutofillOverlayList",
|
||||||
|
theme: ThemeType.Light,
|
||||||
|
},
|
||||||
|
"*",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets a dark theme based on the user's system preferences", () => {
|
||||||
|
window.matchMedia = jest.fn(() => mock<MediaQueryList>({ matches: true }));
|
||||||
|
const message = {
|
||||||
|
command: "initAutofillOverlayList",
|
||||||
|
theme: ThemeType.System,
|
||||||
|
};
|
||||||
|
|
||||||
|
sendPortMessage(portSpy, message);
|
||||||
|
|
||||||
|
expect(window.matchMedia).toHaveBeenCalledWith("(prefers-color-scheme: dark)");
|
||||||
|
expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
|
||||||
|
{
|
||||||
|
command: "initAutofillOverlayList",
|
||||||
|
theme: ThemeType.Dark,
|
||||||
|
},
|
||||||
|
"*",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("updates the border to match the `dark` theme", () => {
|
it("updates the border to match the `dark` theme", () => {
|
||||||
const message = {
|
const message = {
|
||||||
command: "initAutofillOverlayList",
|
command: "initAutofillOverlayList",
|
||||||
theme: "theme_dark",
|
theme: ThemeType.Dark,
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPortMessage(portSpy, message);
|
sendPortMessage(portSpy, message);
|
||||||
@ -239,7 +281,7 @@ describe("AutofillOverlayIframeService", () => {
|
|||||||
it("updates the border to match the `nord` theme", () => {
|
it("updates the border to match the `nord` theme", () => {
|
||||||
const message = {
|
const message = {
|
||||||
command: "initAutofillOverlayList",
|
command: "initAutofillOverlayList",
|
||||||
theme: "theme_nord",
|
theme: ThemeType.Nord,
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPortMessage(portSpy, message);
|
sendPortMessage(portSpy, message);
|
||||||
@ -252,7 +294,7 @@ describe("AutofillOverlayIframeService", () => {
|
|||||||
it("updates the border to match the `solarizedDark` theme", () => {
|
it("updates the border to match the `solarizedDark` theme", () => {
|
||||||
const message = {
|
const message = {
|
||||||
command: "initAutofillOverlayList",
|
command: "initAutofillOverlayList",
|
||||||
theme: "theme_solarizedDark",
|
theme: ThemeType.SolarizedDark,
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPortMessage(portSpy, message);
|
sendPortMessage(portSpy, message);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { ThemeType } from "@bitwarden/common/platform/enums";
|
||||||
|
|
||||||
import { EVENTS } from "../../constants";
|
import { EVENTS } from "../../constants";
|
||||||
import { setElementStyles } from "../../utils";
|
import { setElementStyles } from "../../utils";
|
||||||
import {
|
import {
|
||||||
@ -207,19 +209,27 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
|
|||||||
private initAutofillOverlayList(message: AutofillOverlayIframeExtensionMessage) {
|
private initAutofillOverlayList(message: AutofillOverlayIframeExtensionMessage) {
|
||||||
const { theme } = message;
|
const { theme } = message;
|
||||||
let borderColor: string;
|
let borderColor: string;
|
||||||
if (theme === "theme_dark") {
|
let verifiedTheme = theme;
|
||||||
|
if (verifiedTheme === ThemeType.System) {
|
||||||
|
verifiedTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
|
? ThemeType.Dark
|
||||||
|
: ThemeType.Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verifiedTheme === ThemeType.Dark) {
|
||||||
borderColor = "#4c525f";
|
borderColor = "#4c525f";
|
||||||
}
|
}
|
||||||
if (theme === "theme_nord") {
|
if (theme === ThemeType.Nord) {
|
||||||
borderColor = "#2E3440";
|
borderColor = "#2E3440";
|
||||||
}
|
}
|
||||||
if (theme === "theme_solarizedDark") {
|
if (theme === ThemeType.SolarizedDark) {
|
||||||
borderColor = "#073642";
|
borderColor = "#073642";
|
||||||
}
|
}
|
||||||
if (borderColor) {
|
if (borderColor) {
|
||||||
this.updateElementStyles(this.iframe, { borderColor });
|
this.updateElementStyles(this.iframe, { borderColor });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message.theme = verifiedTheme;
|
||||||
this.iframe.contentWindow?.postMessage(message, "*");
|
this.iframe.contentWindow?.postMessage(message, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
exports[`AutofillOverlayList initAutofillOverlayList the list of ciphers for an authenticated user creates the view for a list of ciphers 1`] = `
|
exports[`AutofillOverlayList initAutofillOverlayList the list of ciphers for an authenticated user creates the view for a list of ciphers 1`] = `
|
||||||
<div
|
<div
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
class="overlay-list-container light"
|
class="overlay-list-container theme_light"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
>
|
>
|
||||||
<ul
|
<ul
|
||||||
@ -437,7 +437,7 @@ exports[`AutofillOverlayList initAutofillOverlayList the list of ciphers for an
|
|||||||
exports[`AutofillOverlayList initAutofillOverlayList the locked overlay for an unauthenticated user creates the views for the locked overlay 1`] = `
|
exports[`AutofillOverlayList initAutofillOverlayList the locked overlay for an unauthenticated user creates the views for the locked overlay 1`] = `
|
||||||
<div
|
<div
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
class="overlay-list-container light"
|
class="overlay-list-container theme_light"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -491,7 +491,7 @@ exports[`AutofillOverlayList initAutofillOverlayList the locked overlay for an u
|
|||||||
exports[`AutofillOverlayList initAutofillOverlayList the overlay with an empty list of ciphers creates the views for the no results overlay 1`] = `
|
exports[`AutofillOverlayList initAutofillOverlayList the overlay with an empty list of ciphers creates the views for the no results overlay 1`] = `
|
||||||
<div
|
<div
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
class="overlay-list-container light"
|
class="overlay-list-container theme_light"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -54,10 +54,11 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
|
|||||||
}: InitAutofillOverlayListMessage) {
|
}: InitAutofillOverlayListMessage) {
|
||||||
const linkElement = this.initOverlayPage("button", styleSheetUrl, translations);
|
const linkElement = this.initOverlayPage("button", styleSheetUrl, translations);
|
||||||
|
|
||||||
globalThis.document.documentElement.classList.add(theme);
|
const themeClass = `theme_${theme}`;
|
||||||
|
globalThis.document.documentElement.classList.add(themeClass);
|
||||||
|
|
||||||
this.overlayListContainer = globalThis.document.createElement("div");
|
this.overlayListContainer = globalThis.document.createElement("div");
|
||||||
this.overlayListContainer.classList.add("overlay-list-container", theme);
|
this.overlayListContainer.classList.add("overlay-list-container", themeClass);
|
||||||
this.overlayListContainer.setAttribute("role", "dialog");
|
this.overlayListContainer.setAttribute("role", "dialog");
|
||||||
this.overlayListContainer.setAttribute("aria-modal", "true");
|
this.overlayListContainer.setAttribute("aria-modal", "true");
|
||||||
this.resizeObserver.observe(this.overlayListContainer);
|
this.resizeObserver.observe(this.overlayListContainer);
|
||||||
|
@ -57,7 +57,7 @@ $themes: (
|
|||||||
inputBorderColor: #4c525f,
|
inputBorderColor: #4c525f,
|
||||||
inputBackgroundColor: #2f343d,
|
inputBackgroundColor: #2f343d,
|
||||||
borderColor: #4c525f,
|
borderColor: #4c525f,
|
||||||
focusOutlineColor: $focus-outline-color,
|
focusOutlineColor: lighten($focus-outline-color, 25%),
|
||||||
successColor: $success-color-dark,
|
successColor: $success-color-dark,
|
||||||
errorColor: $error-color-dark,
|
errorColor: $error-color-dark,
|
||||||
),
|
),
|
||||||
@ -72,7 +72,7 @@ $themes: (
|
|||||||
inputBorderColor: $nord0,
|
inputBorderColor: $nord0,
|
||||||
inputBackgroundColor: $nord2,
|
inputBackgroundColor: $nord2,
|
||||||
borderColor: $nord0,
|
borderColor: $nord0,
|
||||||
focusOutlineColor: $focus-outline-color,
|
focusOutlineColor: lighten($focus-outline-color, 25%),
|
||||||
successColor: $success-color-dark,
|
successColor: $success-color-dark,
|
||||||
),
|
),
|
||||||
solarizedDark: (
|
solarizedDark: (
|
||||||
@ -87,7 +87,7 @@ $themes: (
|
|||||||
inputBorderColor: rgba($solarizedDarkBase2, 0.2),
|
inputBorderColor: rgba($solarizedDarkBase2, 0.2),
|
||||||
inputBackgroundColor: $solarizedDarkBase01,
|
inputBackgroundColor: $solarizedDarkBase01,
|
||||||
borderColor: $solarizedDarkBase2,
|
borderColor: $solarizedDarkBase2,
|
||||||
focusOutlineColor: $focus-outline-color,
|
focusOutlineColor: lighten($focus-outline-color, 15%),
|
||||||
successColor: $success-color-dark,
|
successColor: $success-color-dark,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user