mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
[PM-5189] Working through jest tests for the AutofillOverlayContentService
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
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 { EVENTS, AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
|
import { AutofillOverlayVisibility, EVENTS } from "@bitwarden/common/autofill/constants";
|
||||||
|
|
||||||
import AutofillInit from "../content/autofill-init";
|
import AutofillInit from "../content/autofill-init";
|
||||||
import { AutofillOverlayElement, RedirectFocusDirection } from "../enums/autofill-overlay.enum";
|
import { AutofillOverlayElement, RedirectFocusDirection } from "../enums/autofill-overlay.enum";
|
||||||
import AutofillField from "../models/autofill-field";
|
import AutofillField from "../models/autofill-field";
|
||||||
import { createAutofillFieldMock } from "../spec/autofill-mocks";
|
import { createAutofillFieldMock } from "../spec/autofill-mocks";
|
||||||
import { flushPromises, sendMockExtensionMessage } from "../spec/testing-utils";
|
import { flushPromises, sendMockExtensionMessage } from "../spec/testing-utils";
|
||||||
import { ElementWithOpId, FormFieldElement } from "../types";
|
import { ElementWithOpId, FillableFormFieldElement, FormFieldElement } from "../types";
|
||||||
|
|
||||||
import { AutoFillConstants } from "./autofill-constants";
|
import { AutoFillConstants } from "./autofill-constants";
|
||||||
import { AutofillOverlayContentService } from "./autofill-overlay-content.service";
|
import { AutofillOverlayContentService } from "./autofill-overlay-content.service";
|
||||||
@@ -44,6 +44,10 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
value: 1080,
|
value: 1080,
|
||||||
writable: true,
|
writable: true,
|
||||||
});
|
});
|
||||||
|
Object.defineProperty(window, "top", {
|
||||||
|
value: window,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -327,7 +331,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
jest.spyOn(globalThis.customElements, "define").mockImplementation();
|
jest.spyOn(globalThis.customElements, "define").mockImplementation();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("closes the autofill overlay when the `Escape` key is pressed", () => {
|
it("closes the autofill inline menu when the `Escape` key is pressed", () => {
|
||||||
autofillFieldElement.dispatchEvent(new KeyboardEvent("keyup", { code: "Escape" }));
|
autofillFieldElement.dispatchEvent(new KeyboardEvent("keyup", { code: "Escape" }));
|
||||||
|
|
||||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("closeAutofillInlineMenu", {
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("closeAutofillInlineMenu", {
|
||||||
@@ -509,7 +513,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay if the form field is empty", async () => {
|
it("opens the autofill inline menu if the form field is empty", async () => {
|
||||||
jest.spyOn(autofillOverlayContentService as any, "openAutofillInlineMenu");
|
jest.spyOn(autofillOverlayContentService as any, "openAutofillInlineMenu");
|
||||||
(autofillFieldElement as HTMLInputElement).value = "";
|
(autofillFieldElement as HTMLInputElement).value = "";
|
||||||
|
|
||||||
@@ -523,7 +527,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
expect(autofillOverlayContentService["openAutofillInlineMenu"]).toHaveBeenCalled();
|
expect(autofillOverlayContentService["openAutofillInlineMenu"]).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay if the form field is empty and the user is authed", async () => {
|
it("opens the autofill inline menu if the form field is empty and the user is authed", async () => {
|
||||||
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(true);
|
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(true);
|
||||||
jest.spyOn(autofillOverlayContentService as any, "openAutofillInlineMenu");
|
jest.spyOn(autofillOverlayContentService as any, "openAutofillInlineMenu");
|
||||||
(autofillFieldElement as HTMLInputElement).value = "";
|
(autofillFieldElement as HTMLInputElement).value = "";
|
||||||
@@ -538,7 +542,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
expect(autofillOverlayContentService["openAutofillInlineMenu"]).toHaveBeenCalled();
|
expect(autofillOverlayContentService["openAutofillInlineMenu"]).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay if the form field is empty and the overlay ciphers are not populated", async () => {
|
it("opens the autofill inline menu if the form field is empty and the overlay ciphers are not populated", async () => {
|
||||||
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(false);
|
jest.spyOn(autofillOverlayContentService as any, "isUserAuthed").mockReturnValue(false);
|
||||||
jest
|
jest
|
||||||
.spyOn(autofillOverlayContentService as any, "isInlineMenuCiphersPopulated")
|
.spyOn(autofillOverlayContentService as any, "isInlineMenuCiphersPopulated")
|
||||||
@@ -558,18 +562,10 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("form field click event listener", () => {
|
describe("form field click event listener", () => {
|
||||||
let isInlineMenuButtonVisibleSpy: jest.SpyInstance;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
jest
|
jest
|
||||||
.spyOn(autofillOverlayContentService as any, "triggerFormFieldFocusedAction")
|
.spyOn(autofillOverlayContentService as any, "triggerFormFieldFocusedAction")
|
||||||
.mockImplementation();
|
.mockImplementation();
|
||||||
isInlineMenuButtonVisibleSpy = jest
|
|
||||||
.spyOn(autofillOverlayContentService as any, "isInlineMenuButtonVisible")
|
|
||||||
.mockResolvedValue(false);
|
|
||||||
jest
|
|
||||||
.spyOn(autofillOverlayContentService as any, "isInlineMenuListVisible")
|
|
||||||
.mockResolvedValue(false);
|
|
||||||
await autofillOverlayContentService.setupAutofillInlineMenuListenerOnField(
|
await autofillOverlayContentService.setupAutofillInlineMenuListenerOnField(
|
||||||
autofillFieldElement,
|
autofillFieldElement,
|
||||||
autofillFieldData,
|
autofillFieldData,
|
||||||
@@ -584,7 +580,8 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("skips triggering the field focused handler if the overlay list is visible", () => {
|
it("skips triggering the field focused handler if the overlay list is visible", () => {
|
||||||
isInlineMenuButtonVisibleSpy.mockResolvedValue(true);
|
// Mock resolved value from `isInlineMenuButtonVisible` message
|
||||||
|
sendExtensionMessageSpy.mockResolvedValueOnce(true);
|
||||||
|
|
||||||
autofillFieldElement.dispatchEvent(new Event("click"));
|
autofillFieldElement.dispatchEvent(new Event("click"));
|
||||||
|
|
||||||
@@ -594,7 +591,8 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("skips triggering the field focused handler if the overlay button is visible", () => {
|
it("skips triggering the field focused handler if the overlay button is visible", () => {
|
||||||
isInlineMenuButtonVisibleSpy.mockResolvedValue(true);
|
// Mock resolved value from `isInlineMenuButtonVisible` message
|
||||||
|
sendExtensionMessageSpy.mockResolvedValueOnce(true);
|
||||||
|
|
||||||
autofillFieldElement.dispatchEvent(new Event("click"));
|
autofillFieldElement.dispatchEvent(new Event("click"));
|
||||||
|
|
||||||
@@ -686,7 +684,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay if the form element has no value", async () => {
|
it("opens the autofill inline menu if the form element has no value", async () => {
|
||||||
(autofillFieldElement as HTMLInputElement).value = "";
|
(autofillFieldElement as HTMLInputElement).value = "";
|
||||||
autofillOverlayContentService["inlineMenuVisibility"] =
|
autofillOverlayContentService["inlineMenuVisibility"] =
|
||||||
AutofillOverlayVisibility.OnFieldFocus;
|
AutofillOverlayVisibility.OnFieldFocus;
|
||||||
@@ -701,7 +699,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("openAutofillInlineMenu");
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("openAutofillInlineMenu");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay if the overlay ciphers are not populated and the user is authed", async () => {
|
it("opens the autofill inline menu if the overlay ciphers are not populated and the user is authed", async () => {
|
||||||
(autofillFieldElement as HTMLInputElement).value = "";
|
(autofillFieldElement as HTMLInputElement).value = "";
|
||||||
autofillOverlayContentService["inlineMenuVisibility"] =
|
autofillOverlayContentService["inlineMenuVisibility"] =
|
||||||
AutofillOverlayVisibility.OnFieldFocus;
|
AutofillOverlayVisibility.OnFieldFocus;
|
||||||
@@ -859,10 +857,9 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
<input type="password" id="password-field" placeholder="password" />
|
<input type="password" id="password-field" placeholder="password" />
|
||||||
</form>
|
</form>
|
||||||
`;
|
`;
|
||||||
const usernameField = document.getElementById(
|
autofillOverlayContentService["mostRecentlyFocusedField"] = document.getElementById(
|
||||||
"username-field",
|
"username-field",
|
||||||
) as ElementWithOpId<HTMLInputElement>;
|
) as ElementWithOpId<HTMLInputElement>;
|
||||||
autofillOverlayContentService["mostRecentlyFocusedField"] = usernameField;
|
|
||||||
autofillOverlayContentService["setOverlayRepositionEventListeners"]();
|
autofillOverlayContentService["setOverlayRepositionEventListeners"]();
|
||||||
checkShouldRepositionInlineMenuSpy = jest
|
checkShouldRepositionInlineMenuSpy = jest
|
||||||
.spyOn(autofillOverlayContentService as any, "checkShouldRepositionInlineMenu")
|
.spyOn(autofillOverlayContentService as any, "checkShouldRepositionInlineMenu")
|
||||||
@@ -942,7 +939,9 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
|
|
||||||
globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
|
globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
jest.advanceTimersByTime(800);
|
jest.advanceTimersByTime(750);
|
||||||
|
await flushPromises();
|
||||||
|
jest.advanceTimersByTime(50);
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("updateAutofillInlineMenuPosition", {
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("updateAutofillInlineMenuPosition", {
|
||||||
@@ -954,7 +953,36 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
expect(clearUserInteractionEventTimeoutSpy).toHaveBeenCalled();
|
expect(clearUserInteractionEventTimeoutSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("removes the autofill overlay if the focused field is outside of the viewport", async () => {
|
it("removes the inline menu list if the focused field has a value", async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
jest
|
||||||
|
.spyOn(autofillOverlayContentService as any, "updateMostRecentlyFocusedField")
|
||||||
|
.mockImplementation(() => {
|
||||||
|
autofillOverlayContentService["focusedFieldData"] = {
|
||||||
|
focusedFieldRects: {
|
||||||
|
top: 100,
|
||||||
|
},
|
||||||
|
focusedFieldStyles: {},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
(
|
||||||
|
autofillOverlayContentService["mostRecentlyFocusedField"] as FillableFormFieldElement
|
||||||
|
).value = "test";
|
||||||
|
|
||||||
|
globalThis.dispatchEvent(new Event(EVENTS.SCROLL));
|
||||||
|
await flushPromises();
|
||||||
|
jest.advanceTimersByTime(750);
|
||||||
|
await flushPromises();
|
||||||
|
jest.advanceTimersByTime(50);
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("closeAutofillInlineMenu", {
|
||||||
|
overlayElement: AutofillOverlayElement.List,
|
||||||
|
forceCloseAutofillInlineMenu: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes the autofill inline menu if the focused field is outside of the viewport", async () => {
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
jest
|
jest
|
||||||
.spyOn(autofillOverlayContentService as any, "updateMostRecentlyFocusedField")
|
.spyOn(autofillOverlayContentService as any, "updateMostRecentlyFocusedField")
|
||||||
@@ -1165,7 +1193,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
expect(autofillOverlayContentService["authStatus"]).toEqual(AuthenticationStatus.Unlocked);
|
expect(autofillOverlayContentService["authStatus"]).toEqual(AuthenticationStatus.Unlocked);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens both autofill overlay elements", () => {
|
it("opens both autofill inline menu elements", () => {
|
||||||
autofillOverlayContentService["mostRecentlyFocusedField"] = autofillFieldElement;
|
autofillOverlayContentService["mostRecentlyFocusedField"] = autofillFieldElement;
|
||||||
|
|
||||||
sendMockExtensionMessage({ command: "openAutofillInlineMenu" });
|
sendMockExtensionMessage({ command: "openAutofillInlineMenu" });
|
||||||
@@ -1178,7 +1206,7 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the autofill overlay button only if overlay visibility is set for onButtonClick", () => {
|
it("opens the autofill inline menu button only if overlay visibility is set for onButtonClick", () => {
|
||||||
autofillOverlayContentService["inlineMenuVisibility"] =
|
autofillOverlayContentService["inlineMenuVisibility"] =
|
||||||
AutofillOverlayVisibility.OnButtonClick;
|
AutofillOverlayVisibility.OnButtonClick;
|
||||||
|
|
||||||
@@ -1557,6 +1585,81 @@ describe("AutofillOverlayContentService", () => {
|
|||||||
"*",
|
"*",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("calculateSubFramePositioning", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
autofillOverlayContentService.init();
|
||||||
|
jest.spyOn(globalThis.parent, "postMessage");
|
||||||
|
document.body.innerHTML = ``;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calculates the sub frame offset for the current frame and sends those values to the parent if not in the top frame", async () => {
|
||||||
|
Object.defineProperty(window, "top", {
|
||||||
|
value: null,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
document.body.innerHTML = `<iframe id="subframe" src="https://example.com/"></iframe>`;
|
||||||
|
const iframe = document.querySelector("iframe") as HTMLIFrameElement;
|
||||||
|
const subFrameData = {
|
||||||
|
url: "https://example.com/",
|
||||||
|
frameId: 10,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
parentFrameIds: [1, 2, 3],
|
||||||
|
};
|
||||||
|
const event = mock<MessageEvent>();
|
||||||
|
// @ts-expect-error - Need to mock the source to be the iframe content window
|
||||||
|
event.source = iframe.contentWindow;
|
||||||
|
event.data.subFrameData = subFrameData;
|
||||||
|
sendExtensionMessageSpy.mockResolvedValue(4);
|
||||||
|
|
||||||
|
await autofillOverlayContentService["calculateSubFramePositioning"](event);
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||||
|
{
|
||||||
|
command: "calculateSubFramePositioning",
|
||||||
|
subFrameData: {
|
||||||
|
frameId: 10,
|
||||||
|
left: 2,
|
||||||
|
parentFrameIds: [1, 2, 3, 4],
|
||||||
|
top: 2,
|
||||||
|
url: "https://example.com/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"*",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("posts the calculated sub frame data to the background", async () => {
|
||||||
|
document.body.innerHTML = `<iframe id="subframe" src="https://example.com/"></iframe>`;
|
||||||
|
const iframe = document.querySelector("iframe") as HTMLIFrameElement;
|
||||||
|
const subFrameData = {
|
||||||
|
url: "https://example.com/",
|
||||||
|
frameId: 10,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
parentFrameIds: [1, 2, 3],
|
||||||
|
};
|
||||||
|
const event = mock<MessageEvent>();
|
||||||
|
// @ts-expect-error - Need to mock the source to be the iframe content window
|
||||||
|
event.source = iframe.contentWindow;
|
||||||
|
event.data.subFrameData = subFrameData;
|
||||||
|
|
||||||
|
await autofillOverlayContentService["calculateSubFramePositioning"](event);
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
expect(sendExtensionMessageSpy).toHaveBeenCalledWith("updateSubFrameData", {
|
||||||
|
subFrameData: {
|
||||||
|
frameId: 10,
|
||||||
|
left: 2,
|
||||||
|
top: 2,
|
||||||
|
url: "https://example.com/",
|
||||||
|
parentFrameIds: [1, 2, 3],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("checkMostRecentlyFocusedFieldHasValue", () => {
|
describe("checkMostRecentlyFocusedFieldHasValue", () => {
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
|
|
||||||
if (direction === RedirectFocusDirection.Current) {
|
if (direction === RedirectFocusDirection.Current) {
|
||||||
this.focusMostRecentlyFocusedField();
|
this.focusMostRecentlyFocusedField();
|
||||||
setTimeout(() => void this.sendExtensionMessage("closeAutofillInlineMenu"), 100);
|
globalThis.setTimeout(() => void this.sendExtensionMessage("closeAutofillInlineMenu"), 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +343,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
if (this.mostRecentlyFocusedField && !(await this.isInlineMenuListVisible())) {
|
if (this.mostRecentlyFocusedField && !(await this.isInlineMenuListVisible())) {
|
||||||
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
||||||
this.openAutofillInlineMenu({ isOpeningFullAutofillInlineMenu: true });
|
this.openAutofillInlineMenu({ isOpeningFullAutofillInlineMenu: true });
|
||||||
setTimeout(() => this.sendExtensionMessage("focusAutofillInlineMenuList"), 125);
|
globalThis.setTimeout(() => this.sendExtensionMessage("focusAutofillInlineMenuList"), 125);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +808,10 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
this.rebuildSubFrameOffsets();
|
this.rebuildSubFrameOffsets();
|
||||||
this.toggleAutofillInlineMenuHidden(true);
|
this.toggleAutofillInlineMenuHidden(true);
|
||||||
this.clearUserInteractionEventTimeout();
|
this.clearUserInteractionEventTimeout();
|
||||||
this.userInteractionEventTimeout = setTimeout(this.triggerOverlayRepositionUpdates, 750);
|
this.userInteractionEventTimeout = globalThis.setTimeout(
|
||||||
|
this.triggerOverlayRepositionUpdates,
|
||||||
|
750,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -816,7 +819,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
*/
|
*/
|
||||||
private rebuildSubFrameOffsets() {
|
private rebuildSubFrameOffsets() {
|
||||||
this.clearRecalculateSubFrameOffsetsTimeout();
|
this.clearRecalculateSubFrameOffsetsTimeout();
|
||||||
this.recalculateSubFrameOffsetsTimeout = setTimeout(
|
this.recalculateSubFrameOffsetsTimeout = globalThis.setTimeout(
|
||||||
() => void this.sendExtensionMessage("rebuildSubFrameOffsets"),
|
() => void this.sendExtensionMessage("rebuildSubFrameOffsets"),
|
||||||
150,
|
150,
|
||||||
);
|
);
|
||||||
@@ -837,7 +840,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
|
|
||||||
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
await this.updateMostRecentlyFocusedField(this.mostRecentlyFocusedField);
|
||||||
this.updateAutofillInlineMenuElementsPosition();
|
this.updateAutofillInlineMenuElementsPosition();
|
||||||
setTimeout(async () => {
|
globalThis.setTimeout(async () => {
|
||||||
this.toggleAutofillInlineMenuHidden(false, true);
|
this.toggleAutofillInlineMenuHidden(false, true);
|
||||||
if (
|
if (
|
||||||
await this.hideAutofillInlineMenuListOnFilledField(
|
await this.hideAutofillInlineMenuListOnFilledField(
|
||||||
@@ -931,7 +934,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
* autofill overlay if the document is not visible.
|
* autofill overlay if the document is not visible.
|
||||||
*/
|
*/
|
||||||
private handleVisibilityChangeEvent = () => {
|
private handleVisibilityChangeEvent = () => {
|
||||||
if (!this.mostRecentlyFocusedField || document.visibilityState === "visible") {
|
if (!this.mostRecentlyFocusedField || globalThis.document.visibilityState === "visible") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -968,7 +971,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
const subFrameUrlWithoutTrailingSlash = subFrameUrl?.replace(/\/$/, "");
|
const subFrameUrlWithoutTrailingSlash = subFrameUrl?.replace(/\/$/, "");
|
||||||
|
|
||||||
let iframeElement: HTMLIFrameElement | null = null;
|
let iframeElement: HTMLIFrameElement | null = null;
|
||||||
const iframeElements = document.querySelectorAll(
|
const iframeElements = globalThis.document.querySelectorAll(
|
||||||
`iframe[src="${subFrameUrl}"], iframe[src="${subFrameUrlWithoutTrailingSlash}"]`,
|
`iframe[src="${subFrameUrl}"], iframe[src="${subFrameUrlWithoutTrailingSlash}"]`,
|
||||||
) as NodeListOf<HTMLIFrameElement>;
|
) as NodeListOf<HTMLIFrameElement>;
|
||||||
if (iframeElements.length === 1) {
|
if (iframeElements.length === 1) {
|
||||||
@@ -1052,7 +1055,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
private calculateSubFramePositioning = async (event: MessageEvent) => {
|
private calculateSubFramePositioning = async (event: MessageEvent) => {
|
||||||
const subFrameData = event.data.subFrameData;
|
const subFrameData = event.data.subFrameData;
|
||||||
let subFrameOffsets: SubFrameOffsetData;
|
let subFrameOffsets: SubFrameOffsetData;
|
||||||
const iframes = document.querySelectorAll("iframe");
|
const iframes = globalThis.document.querySelectorAll("iframe");
|
||||||
for (let i = 0; i < iframes.length; i++) {
|
for (let i = 0; i < iframes.length; i++) {
|
||||||
if (iframes[i].contentWindow === event.source) {
|
if (iframes[i].contentWindow === event.source) {
|
||||||
const iframeElement = iframes[i];
|
const iframeElement = iframes[i];
|
||||||
@@ -1061,11 +1064,14 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
subFrameData.url,
|
subFrameData.url,
|
||||||
subFrameData.frameId,
|
subFrameData.frameId,
|
||||||
);
|
);
|
||||||
const parentFrameId = await this.sendExtensionMessage("getCurrentTabFrameId");
|
|
||||||
|
|
||||||
subFrameData.top += subFrameOffsets.top;
|
subFrameData.top += subFrameOffsets.top;
|
||||||
subFrameData.left += subFrameOffsets.left;
|
subFrameData.left += subFrameOffsets.left;
|
||||||
|
|
||||||
|
const parentFrameId = await this.sendExtensionMessage("getCurrentTabFrameId");
|
||||||
|
if (typeof parentFrameId !== "undefined") {
|
||||||
subFrameData.parentFrameIds.push(parentFrameId);
|
subFrameData.parentFrameIds.push(parentFrameId);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1076,7 +1082,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendExtensionMessage("updateSubFrameData", {
|
void this.sendExtensionMessage("updateSubFrameData", {
|
||||||
subFrameData,
|
subFrameData,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user