Skip to content

Commit

Permalink
[PM-5432] Overlay button iframe presents with a white background on w…
Browse files Browse the repository at this point in the history
…ebsites that use dark mode (#7415)

* [PM-5432] Overlay button iframe presents with a white background

* [PM-5432] Adding method that allows us to update the overlay button color scheme dynamically

* [PM-5432] Adding jest tests to validate implementation changes
  • Loading branch information
cagonzalezcs committed Jan 8, 2024
1 parent cc9a347 commit e3f20d8
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";

type OverlayButtonMessage = { command: string };
type OverlayButtonMessage = { command: string; colorScheme?: string };

type UpdateAuthStatusMessage = OverlayButtonMessage & { authStatus: AuthenticationStatus };

Expand All @@ -18,10 +18,12 @@ type OverlayButtonWindowMessageHandlers = {
}: {
message: UpdateAuthStatusMessage;
}) => void;
updateOverlayPageColorScheme: ({ message }: { message: OverlayButtonMessage }) => void;
};

export {
UpdateAuthStatusMessage,
OverlayButtonMessage,
InitAutofillOverlayButtonMessage,
OverlayButtonWindowMessageHandlers,
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type AutofillOverlayIframeExtensionMessage = {
type AutofillOverlayIframeWindowMessageHandlers = {
[key: string]: CallableFunction;
updateAutofillOverlayListHeight: (message: AutofillOverlayIframeExtensionMessage) => void;
getPageColorScheme: () => void;
};

type AutofillOverlayIframeExtensionMessageParam = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,46 @@ describe("AutofillOverlayIframeService", () => {

expect(autofillOverlayIframeService["iframe"].style.height).toBe("300px");
});

describe("getPageColorScheme window message", () => {
afterEach(() => {
globalThis.document.head.innerHTML = "";
});

it("gets and updates the overlay page color scheme", () => {
const colorSchemeMetaTag = globalThis.document.createElement("meta");
colorSchemeMetaTag.setAttribute("name", "color-scheme");
colorSchemeMetaTag.setAttribute("content", "dark");
globalThis.document.head.append(colorSchemeMetaTag);
globalThis.dispatchEvent(
new MessageEvent("message", {
data: { command: "getPageColorScheme" },
source: autofillOverlayIframeService["iframe"].contentWindow,
origin: "chrome-extension://id",
}),
);

expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
{ command: "updateOverlayPageColorScheme", colorScheme: "dark" },
"*",
);
});

it("sends a normal color scheme if the color scheme meta tag is not present", () => {
globalThis.dispatchEvent(
new MessageEvent("message", {
data: { command: "getPageColorScheme" },
source: autofillOverlayIframeService["iframe"].contentWindow,
origin: "chrome-extension://id",
}),
);

expect(autofillOverlayIframeService["iframe"].contentWindow.postMessage).toBeCalledWith(
{ command: "updateOverlayPageColorScheme", colorScheme: "normal" },
"*",
);
});
});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
private readonly windowMessageHandlers: AutofillOverlayIframeWindowMessageHandlers = {
updateAutofillOverlayListHeight: (message) =>
this.updateElementStyles(this.iframe, message.styles),
getPageColorScheme: () => this.updateOverlayPageColorScheme(),
};
private readonly backgroundPortMessageHandlers: BackgroundPortMessageHandlers = {
initAutofillOverlayList: ({ message }) => this.initAutofillOverlayList(message),
Expand Down Expand Up @@ -238,6 +239,22 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
this.announceAriaAlert();
}

/**
* Gets the page color scheme meta tag and sends a message to the iframe
* to update its color scheme. Will default to "normal" if the meta tag
* does not exist.
*/
private updateOverlayPageColorScheme() {
const colorSchemeValue = globalThis.document
.querySelector("meta[name='color-scheme']")
?.getAttribute("content");

this.iframe.contentWindow?.postMessage(
{ command: "updateOverlayPageColorScheme", colorScheme: colorSchemeValue || "normal" },
"*",
);
}

/**
* Handles messages sent from the iframe. If the message does not have a
* specified handler set, it passes the message to the background script.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ describe("AutofillOverlayButton", () => {

postWindowMessage({ command: "checkAutofillOverlayButtonFocused" });

expect(globalThis.parent.postMessage).not.toHaveBeenCalled();
expect(globalThis.parent.postMessage).not.toHaveBeenCalledWith({
command: "closeAutofillOverlay",
});
});

it("posts a message to close the autofill overlay if the element is not focused during the focus check", () => {
Expand All @@ -88,5 +90,19 @@ describe("AutofillOverlayButton", () => {

expect(autofillOverlayButton["authStatus"]).toBe(AuthenticationStatus.Unlocked);
});

it("updates the page color scheme meta tag", () => {
const colorSchemeMetaTag = globalThis.document.createElement("meta");
colorSchemeMetaTag.setAttribute("name", "color-scheme");
colorSchemeMetaTag.setAttribute("content", "light");
globalThis.document.head.append(colorSchemeMetaTag);

postWindowMessage({
command: "updateOverlayPageColorScheme",
colorScheme: "dark",
});

expect(colorSchemeMetaTag.getAttribute("content")).toBe("dark");
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { buildSvgDomElement } from "../../../utils";
import { logoIcon, logoLockedIcon } from "../../../utils/svg-icons";
import {
InitAutofillOverlayButtonMessage,
OverlayButtonMessage,
OverlayButtonWindowMessageHandlers,
} from "../../abstractions/autofill-overlay-button";
import AutofillOverlayPageElement from "../shared/autofill-overlay-page-element";
Expand All @@ -21,6 +22,7 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
checkAutofillOverlayButtonFocused: () => this.checkButtonFocused(),
updateAutofillOverlayButtonAuthStatus: ({ message }) =>
this.updateAuthStatus(message.authStatus),
updateOverlayPageColorScheme: ({ message }) => this.updatePageColorScheme(message),
};

constructor() {
Expand Down Expand Up @@ -61,6 +63,7 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
this.getTranslation("toggleBitwardenVaultOverlay"),
);
this.buttonElement.addEventListener(EVENTS.CLICK, this.handleButtonElementClick);
this.postMessageToParent({ command: "getPageColorScheme" });

this.updateAuthStatus(authStatus);

Expand All @@ -84,6 +87,17 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
this.buttonElement.append(iconElement);
}

/**
* Handles updating the page color scheme meta tag. Ensures that the button
* does not present with a non-transparent background on dark mode pages.
*
* @param colorScheme - The color scheme of the iframe's parent page
*/
private updatePageColorScheme({ colorScheme }: OverlayButtonMessage) {
const colorSchemeMetaTag = globalThis.document.querySelector("meta[name='color-scheme']");
colorSchemeMetaTag?.setAttribute("content", colorScheme);
}

/**
* Handles a click event on the button element. Posts a message to the
* parent window indicating that the button was clicked.
Expand Down

0 comments on commit e3f20d8

Please sign in to comment.