[PM-4415] Refactoring DomElementVisibilityService
This commit is contained in:
parent
b4d6ccf291
commit
57776a32e5
|
@ -1,4 +1,4 @@
|
|||
export interface DomElementVisibilityService {
|
||||
isFormFieldViewable: (element: HTMLElement) => Promise<boolean>;
|
||||
isElementViewable: (element: HTMLElement) => Promise<boolean>;
|
||||
isElementHiddenByCss: (element: HTMLElement) => boolean;
|
||||
}
|
||||
|
|
|
@ -263,8 +263,8 @@ describe("CollectAutofillContentService", () => {
|
|||
collectAutofillContentService["autofillFieldElements"] = new Map([
|
||||
[fieldElement, autofillField],
|
||||
]);
|
||||
const isFormFieldViewableSpy = jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
const isElementViewableSpy = jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
const setupAutofillOverlayListenerOnFieldSpy = jest.spyOn(
|
||||
collectAutofillContentService["autofillOverlayContentService"],
|
||||
|
@ -274,7 +274,7 @@ describe("CollectAutofillContentService", () => {
|
|||
await collectAutofillContentService.getPageDetails();
|
||||
|
||||
expect(autofillField.viewable).toBe(true);
|
||||
expect(isFormFieldViewableSpy).toHaveBeenCalledWith(fieldElement);
|
||||
expect(isElementViewableSpy).toHaveBeenCalledWith(fieldElement);
|
||||
expect(setupAutofillOverlayListenerOnFieldSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -302,7 +302,7 @@ describe("CollectAutofillContentService", () => {
|
|||
jest.spyOn(collectAutofillContentService as any, "buildAutofillFormsData");
|
||||
jest.spyOn(collectAutofillContentService as any, "buildAutofillFieldsData");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
|
||||
const pageDetails = await collectAutofillContentService.getPageDetails();
|
||||
|
@ -564,7 +564,7 @@ describe("CollectAutofillContentService", () => {
|
|||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldElements");
|
||||
jest.spyOn(collectAutofillContentService as any, "buildAutofillFieldItem");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
|
||||
const { formFieldElements } =
|
||||
|
@ -934,7 +934,7 @@ describe("CollectAutofillContentService", () => {
|
|||
collectAutofillContentService["autofillFieldElements"].set(usernameInput, existingFieldData);
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
jest.spyOn(collectAutofillContentService as any, "getPropertyOrAttribute");
|
||||
jest.spyOn(collectAutofillContentService as any, "getElementValue");
|
||||
|
@ -946,7 +946,7 @@ describe("CollectAutofillContentService", () => {
|
|||
|
||||
expect(collectAutofillContentService["getAutofillFieldMaxLength"]).not.toHaveBeenCalled();
|
||||
expect(
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable,
|
||||
collectAutofillContentService["domElementVisibilityService"].isElementViewable,
|
||||
).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).not.toHaveBeenCalled();
|
||||
expect(collectAutofillContentService["getElementValue"]).not.toHaveBeenCalled();
|
||||
|
@ -967,7 +967,7 @@ describe("CollectAutofillContentService", () => {
|
|||
) as ElementWithOpId<FormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
jest.spyOn(collectAutofillContentService as any, "getPropertyOrAttribute");
|
||||
jest.spyOn(collectAutofillContentService as any, "getElementValue");
|
||||
|
@ -981,7 +981,7 @@ describe("CollectAutofillContentService", () => {
|
|||
spanElement,
|
||||
);
|
||||
expect(
|
||||
collectAutofillContentService["domElementVisibilityService"].isFormFieldViewable,
|
||||
collectAutofillContentService["domElementVisibilityService"].isElementViewable,
|
||||
).toHaveBeenCalledWith(spanElement);
|
||||
expect(collectAutofillContentService["getPropertyOrAttribute"]).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
|
@ -1076,7 +1076,7 @@ describe("CollectAutofillContentService", () => {
|
|||
) as ElementWithOpId<FillableFormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
jest.spyOn(collectAutofillContentService as any, "getPropertyOrAttribute");
|
||||
jest.spyOn(collectAutofillContentService as any, "getElementValue");
|
||||
|
@ -1162,7 +1162,7 @@ describe("CollectAutofillContentService", () => {
|
|||
) as ElementWithOpId<FillableFormFieldElement>;
|
||||
jest.spyOn(collectAutofillContentService as any, "getAutofillFieldMaxLength");
|
||||
jest
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isFormFieldViewable")
|
||||
.spyOn(collectAutofillContentService["domElementVisibilityService"], "isElementViewable")
|
||||
.mockResolvedValue(true);
|
||||
jest.spyOn(collectAutofillContentService as any, "getPropertyOrAttribute");
|
||||
jest.spyOn(collectAutofillContentService as any, "getElementValue");
|
||||
|
@ -2507,13 +2507,13 @@ describe("CollectAutofillContentService", () => {
|
|||
});
|
||||
|
||||
describe("handleFormElementIntersection", () => {
|
||||
let isFormFieldViewableSpy: jest.SpyInstance;
|
||||
let isElementViewableSpy: jest.SpyInstance;
|
||||
let setupAutofillOverlayListenerOnFieldSpy: jest.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
isFormFieldViewableSpy = jest.spyOn(
|
||||
isElementViewableSpy = jest.spyOn(
|
||||
collectAutofillContentService["domElementVisibilityService"],
|
||||
"isFormFieldViewable",
|
||||
"isElementViewable",
|
||||
);
|
||||
setupAutofillOverlayListenerOnFieldSpy = jest.spyOn(
|
||||
collectAutofillContentService["autofillOverlayContentService"],
|
||||
|
@ -2532,7 +2532,7 @@ describe("CollectAutofillContentService", () => {
|
|||
|
||||
await collectAutofillContentService["handleFormElementIntersection"](entries);
|
||||
|
||||
expect(isFormFieldViewableSpy).not.toHaveBeenCalled();
|
||||
expect(isElementViewableSpy).not.toHaveBeenCalled();
|
||||
expect(setupAutofillOverlayListenerOnFieldSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -2543,11 +2543,11 @@ describe("CollectAutofillContentService", () => {
|
|||
{ target: formFieldElement, isIntersecting: true },
|
||||
] as unknown as IntersectionObserverEntry[];
|
||||
collectAutofillContentService["autofillFieldElements"].set(formFieldElement, autofillField);
|
||||
isFormFieldViewableSpy.mockReturnValueOnce(false);
|
||||
isElementViewableSpy.mockReturnValueOnce(false);
|
||||
|
||||
await collectAutofillContentService["handleFormElementIntersection"](entries);
|
||||
|
||||
expect(isFormFieldViewableSpy).toHaveBeenCalledWith(formFieldElement);
|
||||
expect(isElementViewableSpy).toHaveBeenCalledWith(formFieldElement);
|
||||
expect(setupAutofillOverlayListenerOnFieldSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -2556,12 +2556,12 @@ describe("CollectAutofillContentService", () => {
|
|||
const entries = [
|
||||
{ target: formFieldElement, isIntersecting: true },
|
||||
] as unknown as IntersectionObserverEntry[];
|
||||
isFormFieldViewableSpy.mockReturnValueOnce(true);
|
||||
isElementViewableSpy.mockReturnValueOnce(true);
|
||||
collectAutofillContentService["intersectionObserver"] = mockIntersectionObserver;
|
||||
|
||||
await collectAutofillContentService["handleFormElementIntersection"](entries);
|
||||
|
||||
expect(isFormFieldViewableSpy).not.toHaveBeenCalled();
|
||||
expect(isElementViewableSpy).not.toHaveBeenCalled();
|
||||
expect(setupAutofillOverlayListenerOnFieldSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@ -2571,13 +2571,13 @@ describe("CollectAutofillContentService", () => {
|
|||
const entries = [
|
||||
{ target: formFieldElement, isIntersecting: true },
|
||||
] as unknown as IntersectionObserverEntry[];
|
||||
isFormFieldViewableSpy.mockReturnValueOnce(true);
|
||||
isElementViewableSpy.mockReturnValueOnce(true);
|
||||
collectAutofillContentService["autofillFieldElements"].set(formFieldElement, autofillField);
|
||||
collectAutofillContentService["intersectionObserver"] = mockIntersectionObserver;
|
||||
|
||||
await collectAutofillContentService["handleFormElementIntersection"](entries);
|
||||
|
||||
expect(isFormFieldViewableSpy).toHaveBeenCalledWith(formFieldElement);
|
||||
expect(isElementViewableSpy).toHaveBeenCalledWith(formFieldElement);
|
||||
expect(setupAutofillOverlayListenerOnFieldSpy).toHaveBeenCalledWith(
|
||||
formFieldElement,
|
||||
autofillField,
|
||||
|
|
|
@ -196,7 +196,7 @@ export class CollectAutofillContentService implements CollectAutofillContentServ
|
|||
private updateCachedAutofillFieldVisibility() {
|
||||
this.autofillFieldElements.forEach(async (autofillField, element) => {
|
||||
const previouslyViewable = autofillField.viewable;
|
||||
autofillField.viewable = await this.domElementVisibilityService.isFormFieldViewable(element);
|
||||
autofillField.viewable = await this.domElementVisibilityService.isElementViewable(element);
|
||||
|
||||
if (!previouslyViewable && autofillField.viewable) {
|
||||
this.setupOverlayOnField(element, autofillField);
|
||||
|
@ -360,7 +360,7 @@ export class CollectAutofillContentService implements CollectAutofillContentServ
|
|||
opid: element.opid,
|
||||
elementNumber: index,
|
||||
maxLength: this.getAutofillFieldMaxLength(element),
|
||||
viewable: await this.domElementVisibilityService.isFormFieldViewable(element),
|
||||
viewable: await this.domElementVisibilityService.isElementViewable(element),
|
||||
htmlID: this.getPropertyOrAttribute(element, "id"),
|
||||
htmlName: this.getPropertyOrAttribute(element, "name"),
|
||||
htmlClass: this.getPropertyOrAttribute(element, "class"),
|
||||
|
@ -1332,8 +1332,7 @@ export class CollectAutofillContentService implements CollectAutofillContentServ
|
|||
continue;
|
||||
}
|
||||
|
||||
const isViewable =
|
||||
await this.domElementVisibilityService.isFormFieldViewable(formFieldElement);
|
||||
const isViewable = await this.domElementVisibilityService.isElementViewable(formFieldElement);
|
||||
if (!isViewable) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ describe("DomElementVisibilityService", () => {
|
|||
document.body.innerHTML = "";
|
||||
});
|
||||
|
||||
describe("isFormFieldViewable", () => {
|
||||
describe("isElementViewable", () => {
|
||||
it("returns false if the element is outside viewport bounds", async () => {
|
||||
const usernameElement = document.querySelector("input[name='username']") as FormFieldElement;
|
||||
jest.spyOn(usernameElement, "getBoundingClientRect");
|
||||
|
@ -47,10 +47,10 @@ describe("DomElementVisibilityService", () => {
|
|||
jest.spyOn(domElementVisibilityService, "isElementHiddenByCss");
|
||||
jest.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement");
|
||||
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
const isElementViewable =
|
||||
await domElementVisibilityService.isElementViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(isElementViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
|
@ -71,10 +71,10 @@ describe("DomElementVisibilityService", () => {
|
|||
jest.spyOn(domElementVisibilityService, "isElementHiddenByCss").mockReturnValueOnce(true);
|
||||
jest.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement");
|
||||
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
const isElementViewable =
|
||||
await domElementVisibilityService.isElementViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(isElementViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
|
@ -99,10 +99,10 @@ describe("DomElementVisibilityService", () => {
|
|||
.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement")
|
||||
.mockReturnValueOnce(false);
|
||||
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
const isElementViewable =
|
||||
await domElementVisibilityService.isElementViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(false);
|
||||
expect(isElementViewable).toEqual(false);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
|
@ -127,10 +127,10 @@ describe("DomElementVisibilityService", () => {
|
|||
.spyOn(domElementVisibilityService as any, "formFieldIsNotHiddenBehindAnotherElement")
|
||||
.mockReturnValueOnce(true);
|
||||
|
||||
const isFormFieldViewable =
|
||||
await domElementVisibilityService.isFormFieldViewable(usernameElement);
|
||||
const isElementViewable =
|
||||
await domElementVisibilityService.isElementViewable(usernameElement);
|
||||
|
||||
expect(isFormFieldViewable).toEqual(true);
|
||||
expect(isElementViewable).toEqual(true);
|
||||
expect(usernameElement.getBoundingClientRect).toHaveBeenCalled();
|
||||
expect(domElementVisibilityService["isElementOutsideViewportBounds"]).toHaveBeenCalledWith(
|
||||
usernameElement,
|
||||
|
|
|
@ -9,12 +9,11 @@ class DomElementVisibilityService implements DomElementVisibilityServiceInterfac
|
|||
constructor(private inlineMenuContentService?: AutofillInlineMenuContentService) {}
|
||||
|
||||
/**
|
||||
* Checks if a form field is viewable. This is done by checking if the element is within the
|
||||
* Checks if an element is viewable. This is done by checking if the element is within the
|
||||
* viewport bounds, not hidden by CSS, and not hidden behind another element.
|
||||
* @param {FormFieldElement} element
|
||||
* @returns {Promise<boolean>}
|
||||
* @param element
|
||||
*/
|
||||
async isFormFieldViewable(element: FormFieldElement): Promise<boolean> {
|
||||
async isElementViewable(element: HTMLElement): Promise<boolean> {
|
||||
const elementBoundingClientRect = element.getBoundingClientRect();
|
||||
if (
|
||||
this.isElementOutsideViewportBounds(element, elementBoundingClientRect) ||
|
||||
|
|
Loading…
Reference in New Issue