[PM-4415] Reworking placement of the DomElementVisibilityService instantiation to ensure it can be used in the OverlayContentService

This commit is contained in:
Cesar Gonzalez 2024-10-08 08:14:11 -05:00
parent 377fae713c
commit b4d6ccf291
No known key found for this signature in database
GPG Key ID: 3381A5457F8CCECF
14 changed files with 73 additions and 28 deletions

View File

@ -4,6 +4,7 @@ import AutofillPageDetails from "../models/autofill-page-details";
import AutofillScript from "../models/autofill-script";
import { AutofillInlineMenuContentService } from "../overlay/inline-menu/content/autofill-inline-menu-content.service";
import { OverlayNotificationsContentService } from "../overlay/notifications/abstractions/overlay-notifications-content.service";
import { DomElementVisibilityService } from "../services/abstractions/dom-element-visibility.service";
import { DomQueryService } from "../services/abstractions/dom-query.service";
import { AutofillOverlayContentService } from "../services/autofill-overlay-content.service";
import {
@ -17,6 +18,7 @@ import AutofillInit from "./autofill-init";
describe("AutofillInit", () => {
let domQueryService: MockProxy<DomQueryService>;
let domElementVisibilityService: MockProxy<DomElementVisibilityService>;
let overlayNotificationsContentService: MockProxy<OverlayNotificationsContentService>;
let inlineMenuElements: MockProxy<AutofillInlineMenuContentService>;
let autofillOverlayContentService: MockProxy<AutofillOverlayContentService>;
@ -32,11 +34,13 @@ describe("AutofillInit", () => {
},
});
domQueryService = mock<DomQueryService>();
domElementVisibilityService = mock<DomElementVisibilityService>();
overlayNotificationsContentService = mock<OverlayNotificationsContentService>();
inlineMenuElements = mock<AutofillInlineMenuContentService>();
autofillOverlayContentService = mock<AutofillOverlayContentService>();
autofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
autofillOverlayContentService,
inlineMenuElements,
overlayNotificationsContentService,

View File

@ -4,9 +4,9 @@ import AutofillPageDetails from "../models/autofill-page-details";
import { AutofillInlineMenuContentService } from "../overlay/inline-menu/abstractions/autofill-inline-menu-content.service";
import { OverlayNotificationsContentService } from "../overlay/notifications/abstractions/overlay-notifications-content.service";
import { AutofillOverlayContentService } from "../services/abstractions/autofill-overlay-content.service";
import { DomElementVisibilityService } from "../services/abstractions/dom-element-visibility.service";
import { DomQueryService } from "../services/abstractions/dom-query.service";
import { CollectAutofillContentService } from "../services/collect-autofill-content.service";
import DomElementVisibilityService from "../services/dom-element-visibility.service";
import InsertAutofillContentService from "../services/insert-autofill-content.service";
import { sendExtensionMessage } from "../utils";
@ -18,7 +18,6 @@ import {
class AutofillInit implements AutofillInitInterface {
private readonly sendExtensionMessage = sendExtensionMessage;
private readonly domElementVisibilityService: DomElementVisibilityService;
private readonly collectAutofillContentService: CollectAutofillContentService;
private readonly insertAutofillContentService: InsertAutofillContentService;
private collectPageDetailsOnLoadTimeout: number | NodeJS.Timeout | undefined;
@ -33,26 +32,25 @@ class AutofillInit implements AutofillInitInterface {
* CollectAutofillContentService and InsertAutofillContentService classes.
*
* @param domQueryService - Service used to handle DOM queries.
* @param domElementVisibilityService - Used to check if an element is viewable.
* @param autofillOverlayContentService - The autofill overlay content service, potentially undefined.
* @param autofillInlineMenuContentService - The inline menu content service, potentially undefined.
* @param overlayNotificationsContentService - The overlay notifications content service, potentially undefined.
*/
constructor(
domQueryService: DomQueryService,
domElementVisibilityService: DomElementVisibilityService,
private autofillOverlayContentService?: AutofillOverlayContentService,
private autofillInlineMenuContentService?: AutofillInlineMenuContentService,
private overlayNotificationsContentService?: OverlayNotificationsContentService,
) {
this.domElementVisibilityService = new DomElementVisibilityService(
this.autofillInlineMenuContentService,
);
this.collectAutofillContentService = new CollectAutofillContentService(
this.domElementVisibilityService,
domElementVisibilityService,
domQueryService,
this.autofillOverlayContentService,
);
this.insertAutofillContentService = new InsertAutofillContentService(
this.domElementVisibilityService,
domElementVisibilityService,
this.collectAutofillContentService,
);
}

View File

@ -1,5 +1,6 @@
import { AutofillInlineMenuContentService } from "../overlay/inline-menu/content/autofill-inline-menu-content.service";
import { AutofillOverlayContentService } from "../services/autofill-overlay-content.service";
import DomElementVisibilityService from "../services/dom-element-visibility.service";
import { DomQueryService } from "../services/dom-query.service";
import { InlineMenuFieldQualificationService } from "../services/inline-menu-field-qualification.service";
import { setupAutofillInitDisconnectAction } from "../utils";
@ -8,20 +9,25 @@ import AutofillInit from "./autofill-init";
(function (windowContext) {
if (!windowContext.bitwardenAutofillInit) {
let inlineMenuContentService: AutofillInlineMenuContentService;
if (globalThis.self === globalThis.top) {
inlineMenuContentService = new AutofillInlineMenuContentService();
}
const domQueryService = new DomQueryService();
const domElementVisibilityService = new DomElementVisibilityService(inlineMenuContentService);
const inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
let inlineMenuElements: AutofillInlineMenuContentService;
if (globalThis.self === globalThis.top) {
inlineMenuElements = new AutofillInlineMenuContentService();
}
windowContext.bitwardenAutofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
autofillOverlayContentService,
inlineMenuElements,
inlineMenuContentService,
);
setupAutofillInitDisconnectAction(windowContext);

View File

@ -1,5 +1,6 @@
import { OverlayNotificationsContentService } from "../overlay/notifications/content/overlay-notifications-content.service";
import { AutofillOverlayContentService } from "../services/autofill-overlay-content.service";
import DomElementVisibilityService from "../services/dom-element-visibility.service";
import { DomQueryService } from "../services/dom-query.service";
import { InlineMenuFieldQualificationService } from "../services/inline-menu-field-qualification.service";
import { setupAutofillInitDisconnectAction } from "../utils";
@ -9,9 +10,11 @@ import AutofillInit from "./autofill-init";
(function (windowContext) {
if (!windowContext.bitwardenAutofillInit) {
const domQueryService = new DomQueryService();
const domElementVisibilityService = new DomElementVisibilityService();
const inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
@ -22,6 +25,7 @@ import AutofillInit from "./autofill-init";
windowContext.bitwardenAutofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
autofillOverlayContentService,
null,
overlayNotificationsContentService,

View File

@ -1,6 +1,7 @@
import { AutofillInlineMenuContentService } from "../overlay/inline-menu/content/autofill-inline-menu-content.service";
import { OverlayNotificationsContentService } from "../overlay/notifications/content/overlay-notifications-content.service";
import { AutofillOverlayContentService } from "../services/autofill-overlay-content.service";
import DomElementVisibilityService from "../services/dom-element-visibility.service";
import { DomQueryService } from "../services/dom-query.service";
import { InlineMenuFieldQualificationService } from "../services/inline-menu-field-qualification.service";
import { setupAutofillInitDisconnectAction } from "../utils";
@ -9,24 +10,27 @@ import AutofillInit from "./autofill-init";
(function (windowContext) {
if (!windowContext.bitwardenAutofillInit) {
const domQueryService = new DomQueryService();
const inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
inlineMenuFieldQualificationService,
);
let inlineMenuElements: AutofillInlineMenuContentService;
let inlineMenuContentService: AutofillInlineMenuContentService;
let overlayNotificationsContentService: OverlayNotificationsContentService;
if (globalThis.self === globalThis.top) {
inlineMenuElements = new AutofillInlineMenuContentService();
inlineMenuContentService = new AutofillInlineMenuContentService();
overlayNotificationsContentService = new OverlayNotificationsContentService();
}
const domQueryService = new DomQueryService();
const domElementVisibilityService = new DomElementVisibilityService(inlineMenuContentService);
const inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
windowContext.bitwardenAutofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
autofillOverlayContentService,
inlineMenuElements,
inlineMenuContentService,
overlayNotificationsContentService,
);
setupAutofillInitDisconnectAction(windowContext);

View File

@ -1,3 +1,4 @@
import DomElementVisibilityService from "../services/dom-element-visibility.service";
import { DomQueryService } from "../services/dom-query.service";
import { setupAutofillInitDisconnectAction } from "../utils";
@ -6,7 +7,11 @@ import AutofillInit from "./autofill-init";
(function (windowContext) {
if (!windowContext.bitwardenAutofillInit) {
const domQueryService = new DomQueryService();
windowContext.bitwardenAutofillInit = new AutofillInit(domQueryService);
const domElementVisibilityService = new DomElementVisibilityService();
windowContext.bitwardenAutofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
);
setupAutofillInitDisconnectAction(windowContext);
windowContext.bitwardenAutofillInit.init();

View File

@ -3,6 +3,7 @@ import { mock, MockProxy } from "jest-mock-extended";
import AutofillInit from "../../../content/autofill-init";
import { AutofillOverlayElement } from "../../../enums/autofill-overlay.enum";
import { DomQueryService } from "../../../services/abstractions/dom-query.service";
import DomElementVisibilityService from "../../../services/dom-element-visibility.service";
import { createMutationRecordMock } from "../../../spec/autofill-mocks";
import { flushPromises, sendMockExtensionMessage } from "../../../spec/testing-utils";
import { ElementWithOpId } from "../../../types";
@ -11,6 +12,7 @@ import { AutofillInlineMenuContentService } from "./autofill-inline-menu-content
describe("AutofillInlineMenuContentService", () => {
let domQueryService: MockProxy<DomQueryService>;
let domElementVisibilityService: DomElementVisibilityService;
let autofillInlineMenuContentService: AutofillInlineMenuContentService;
let autofillInit: AutofillInit;
let sendExtensionMessageSpy: jest.SpyInstance;
@ -22,8 +24,14 @@ describe("AutofillInlineMenuContentService", () => {
globalThis.document.body.innerHTML = "";
globalThis.requestIdleCallback = jest.fn((cb, options) => setTimeout(cb, 100));
domQueryService = mock<DomQueryService>();
domElementVisibilityService = new DomElementVisibilityService();
autofillInlineMenuContentService = new AutofillInlineMenuContentService();
autofillInit = new AutofillInit(domQueryService, null, autofillInlineMenuContentService);
autofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
null,
autofillInlineMenuContentService,
);
autofillInit.init();
observeBodyMutationsSpy = jest.spyOn(
autofillInlineMenuContentService["bodyElementMutationObserver"] as any,

View File

@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended";
import AutofillInit from "../../../content/autofill-init";
import { DomQueryService } from "../../../services/abstractions/dom-query.service";
import DomElementVisibilityService from "../../../services/dom-element-visibility.service";
import { flushPromises, sendMockExtensionMessage } from "../../../spec/testing-utils";
import { NotificationTypeData } from "../abstractions/overlay-notifications-content.service";
@ -10,15 +11,18 @@ import { OverlayNotificationsContentService } from "./overlay-notifications-cont
describe("OverlayNotificationsContentService", () => {
let overlayNotificationsContentService: OverlayNotificationsContentService;
let domQueryService: MockProxy<DomQueryService>;
let domElementVisibilityService: DomElementVisibilityService;
let autofillInit: AutofillInit;
let bodyAppendChildSpy: jest.SpyInstance;
beforeEach(() => {
jest.useFakeTimers();
domQueryService = mock<DomQueryService>();
domElementVisibilityService = new DomElementVisibilityService();
overlayNotificationsContentService = new OverlayNotificationsContentService();
autofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
null,
null,
overlayNotificationsContentService,

View File

@ -24,6 +24,7 @@ import { ElementWithOpId, FillableFormFieldElement, FormFieldElement } from "../
import { AutoFillConstants } from "./autofill-constants";
import { AutofillOverlayContentService } from "./autofill-overlay-content.service";
import DomElementVisibilityService from "./dom-element-visibility.service";
import { DomQueryService } from "./dom-query.service";
import { InlineMenuFieldQualificationService } from "./inline-menu-field-qualification.service";
@ -31,6 +32,7 @@ const defaultWindowReadyState = document.readyState;
const defaultDocumentVisibilityState = document.visibilityState;
describe("AutofillOverlayContentService", () => {
let domQueryService: DomQueryService;
let domElementVisibilityService: DomElementVisibilityService;
let autofillInit: AutofillInit;
let inlineMenuFieldQualificationService: InlineMenuFieldQualificationService;
let autofillOverlayContentService: AutofillOverlayContentService;
@ -41,11 +43,17 @@ describe("AutofillOverlayContentService", () => {
beforeEach(async () => {
inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService();
domQueryService = new DomQueryService();
domElementVisibilityService = new DomElementVisibilityService();
autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
autofillInit = new AutofillInit(domQueryService, autofillOverlayContentService);
autofillInit = new AutofillInit(
domQueryService,
domElementVisibilityService,
autofillOverlayContentService,
);
autofillInit.init();
autofillOverlayContentService["showInlineMenuCards"] = true;
autofillOverlayContentService["showInlineMenuIdentities"] = true;

View File

@ -46,6 +46,7 @@ import {
InlineMenuFormFieldData,
SubFrameDataFromWindowMessage,
} from "./abstractions/autofill-overlay-content.service";
import { DomElementVisibilityService } from "./abstractions/dom-element-visibility.service";
import { DomQueryService } from "./abstractions/dom-query.service";
import { InlineMenuFieldQualificationService } from "./abstractions/inline-menu-field-qualifications.service";
import { AutoFillConstants } from "./autofill-constants";
@ -150,6 +151,7 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ
constructor(
private domQueryService: DomQueryService,
private domElementVisibilityService: DomElementVisibilityService,
private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService,
) {}

View File

@ -43,6 +43,7 @@ describe("CollectAutofillContentService", () => {
const domQueryService = new DomQueryService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
let collectAutofillContentService: CollectAutofillContentService;

View File

@ -6,7 +6,7 @@ import { DomElementVisibilityService as DomElementVisibilityServiceInterface } f
class DomElementVisibilityService implements DomElementVisibilityServiceInterface {
private cachedComputedStyle: CSSStyleDeclaration | null = null;
constructor(private inlineMenuElements?: AutofillInlineMenuContentService) {}
constructor(private inlineMenuContentService?: AutofillInlineMenuContentService) {}
/**
* Checks if a form field is viewable. This is done by checking if the element is within the
@ -190,7 +190,7 @@ class DomElementVisibilityService implements DomElementVisibilityServiceInterfac
return true;
}
if (this.inlineMenuElements?.isElementInlineMenu(elementAtCenterPoint as HTMLElement)) {
if (this.inlineMenuContentService?.isElementInlineMenu(elementAtCenterPoint as HTMLElement)) {
return true;
}

View File

@ -74,6 +74,7 @@ describe("InsertAutofillContentService", () => {
const domElementVisibilityService = new DomElementVisibilityService();
const autofillOverlayContentService = new AutofillOverlayContentService(
domQueryService,
domElementVisibilityService,
inlineMenuFieldQualificationService,
);
const collectAutofillContentService = new CollectAutofillContentService(

View File

@ -10,9 +10,9 @@ import {
elementIsTextAreaElement,
} from "../utils";
import { DomElementVisibilityService } from "./abstractions/dom-element-visibility.service";
import { InsertAutofillContentService as InsertAutofillContentServiceInterface } from "./abstractions/insert-autofill-content.service";
import { CollectAutofillContentService } from "./collect-autofill-content.service";
import DomElementVisibilityService from "./dom-element-visibility.service";
class InsertAutofillContentService implements InsertAutofillContentServiceInterface {
private readonly autofillInsertActions: AutofillInsertActions = {