From b4d6ccf2918062d55932111e434a834acada012b Mon Sep 17 00:00:00 2001 From: Cesar Gonzalez Date: Tue, 8 Oct 2024 08:14:11 -0500 Subject: [PATCH] [PM-4415] Reworking placement of the DomElementVisibilityService instantiation to ensure it can be used in the OverlayContentService --- .../autofill/content/autofill-init.spec.ts | 4 ++++ .../src/autofill/content/autofill-init.ts | 12 ++++------ .../bootstrap-autofill-overlay-menu.ts | 16 +++++++++---- ...ootstrap-autofill-overlay-notifications.ts | 4 ++++ .../content/bootstrap-autofill-overlay.ts | 24 +++++++++++-------- .../autofill/content/bootstrap-autofill.ts | 7 +++++- ...tofill-inline-menu-content.service.spec.ts | 10 +++++++- ...rlay-notifications-content.service.spec.ts | 4 ++++ .../autofill-overlay-content.service.spec.ts | 10 +++++++- .../autofill-overlay-content.service.ts | 2 ++ .../collect-autofill-content.service.spec.ts | 1 + .../dom-element-visibility.service.ts | 4 ++-- .../insert-autofill-content.service.spec.ts | 1 + .../insert-autofill-content.service.ts | 2 +- 14 files changed, 73 insertions(+), 28 deletions(-) diff --git a/apps/browser/src/autofill/content/autofill-init.spec.ts b/apps/browser/src/autofill/content/autofill-init.spec.ts index b98d297d13..d612e63f82 100644 --- a/apps/browser/src/autofill/content/autofill-init.spec.ts +++ b/apps/browser/src/autofill/content/autofill-init.spec.ts @@ -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; + let domElementVisibilityService: MockProxy; let overlayNotificationsContentService: MockProxy; let inlineMenuElements: MockProxy; let autofillOverlayContentService: MockProxy; @@ -32,11 +34,13 @@ describe("AutofillInit", () => { }, }); domQueryService = mock(); + domElementVisibilityService = mock(); overlayNotificationsContentService = mock(); inlineMenuElements = mock(); autofillOverlayContentService = mock(); autofillInit = new AutofillInit( domQueryService, + domElementVisibilityService, autofillOverlayContentService, inlineMenuElements, overlayNotificationsContentService, diff --git a/apps/browser/src/autofill/content/autofill-init.ts b/apps/browser/src/autofill/content/autofill-init.ts index 6c34508cb0..42933c57b1 100644 --- a/apps/browser/src/autofill/content/autofill-init.ts +++ b/apps/browser/src/autofill/content/autofill-init.ts @@ -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, ); } diff --git a/apps/browser/src/autofill/content/bootstrap-autofill-overlay-menu.ts b/apps/browser/src/autofill/content/bootstrap-autofill-overlay-menu.ts index aed0f6cb94..3593064792 100644 --- a/apps/browser/src/autofill/content/bootstrap-autofill-overlay-menu.ts +++ b/apps/browser/src/autofill/content/bootstrap-autofill-overlay-menu.ts @@ -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); diff --git a/apps/browser/src/autofill/content/bootstrap-autofill-overlay-notifications.ts b/apps/browser/src/autofill/content/bootstrap-autofill-overlay-notifications.ts index 0a810c68f5..6fbb076389 100644 --- a/apps/browser/src/autofill/content/bootstrap-autofill-overlay-notifications.ts +++ b/apps/browser/src/autofill/content/bootstrap-autofill-overlay-notifications.ts @@ -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, diff --git a/apps/browser/src/autofill/content/bootstrap-autofill-overlay.ts b/apps/browser/src/autofill/content/bootstrap-autofill-overlay.ts index 6df9397f6d..174a695b76 100644 --- a/apps/browser/src/autofill/content/bootstrap-autofill-overlay.ts +++ b/apps/browser/src/autofill/content/bootstrap-autofill-overlay.ts @@ -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); diff --git a/apps/browser/src/autofill/content/bootstrap-autofill.ts b/apps/browser/src/autofill/content/bootstrap-autofill.ts index 3de750cd67..ada66f233c 100644 --- a/apps/browser/src/autofill/content/bootstrap-autofill.ts +++ b/apps/browser/src/autofill/content/bootstrap-autofill.ts @@ -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(); diff --git a/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.spec.ts b/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.spec.ts index 8d5e08fc08..e2790fa680 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.spec.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/content/autofill-inline-menu-content.service.spec.ts @@ -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; + 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(); + 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, diff --git a/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.spec.ts b/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.spec.ts index f7240b33db..8a8ccdf363 100644 --- a/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.spec.ts +++ b/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.spec.ts @@ -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; + let domElementVisibilityService: DomElementVisibilityService; let autofillInit: AutofillInit; let bodyAppendChildSpy: jest.SpyInstance; beforeEach(() => { jest.useFakeTimers(); domQueryService = mock(); + domElementVisibilityService = new DomElementVisibilityService(); overlayNotificationsContentService = new OverlayNotificationsContentService(); autofillInit = new AutofillInit( domQueryService, + domElementVisibilityService, null, null, overlayNotificationsContentService, diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts index a05e7a5832..9fc57d5e79 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts @@ -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; diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts index f48583f41e..8f67e41a59 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts @@ -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, ) {} diff --git a/apps/browser/src/autofill/services/collect-autofill-content.service.spec.ts b/apps/browser/src/autofill/services/collect-autofill-content.service.spec.ts index 48ffd291b5..51bc430acd 100644 --- a/apps/browser/src/autofill/services/collect-autofill-content.service.spec.ts +++ b/apps/browser/src/autofill/services/collect-autofill-content.service.spec.ts @@ -43,6 +43,7 @@ describe("CollectAutofillContentService", () => { const domQueryService = new DomQueryService(); const autofillOverlayContentService = new AutofillOverlayContentService( domQueryService, + domElementVisibilityService, inlineMenuFieldQualificationService, ); let collectAutofillContentService: CollectAutofillContentService; diff --git a/apps/browser/src/autofill/services/dom-element-visibility.service.ts b/apps/browser/src/autofill/services/dom-element-visibility.service.ts index 9df4ccb8fb..90d6fbdb11 100644 --- a/apps/browser/src/autofill/services/dom-element-visibility.service.ts +++ b/apps/browser/src/autofill/services/dom-element-visibility.service.ts @@ -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; } diff --git a/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts b/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts index 150ccc21c5..e36d6811ec 100644 --- a/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts +++ b/apps/browser/src/autofill/services/insert-autofill-content.service.spec.ts @@ -74,6 +74,7 @@ describe("InsertAutofillContentService", () => { const domElementVisibilityService = new DomElementVisibilityService(); const autofillOverlayContentService = new AutofillOverlayContentService( domQueryService, + domElementVisibilityService, inlineMenuFieldQualificationService, ); const collectAutofillContentService = new CollectAutofillContentService( diff --git a/apps/browser/src/autofill/services/insert-autofill-content.service.ts b/apps/browser/src/autofill/services/insert-autofill-content.service.ts index cc4ee5a5e4..813baa5922 100644 --- a/apps/browser/src/autofill/services/insert-autofill-content.service.ts +++ b/apps/browser/src/autofill/services/insert-autofill-content.service.ts @@ -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 = {