1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

[PM-17407] [CL-665] Remove jQuery and Popper.js (#14621)

Now that the last usages of ModalService is removed from the web portions we can finally remove jQuery and Popper.js. This PR also removes bootstrap js imports since it would drag in jQuery as a peer dependency.

Note: Both dependencies still exists in the lockfile as they are peer dependencies of boostrap.
This commit is contained in:
Oscar Hinton
2025-05-13 21:36:26 +02:00
committed by GitHub
parent 1cc06fd3b9
commit bacd1fb999
8 changed files with 4 additions and 121 deletions

View File

@@ -222,7 +222,6 @@
"@types/chrome",
"@types/firefox-webext-browser",
"@types/glob",
"@types/jquery",
"@types/lowdb",
"@types/node",
"@types/node-forge",
@@ -330,9 +329,7 @@
"autoprefixer",
"bootstrap",
"chromatic",
"jquery",
"ngx-toastr",
"popper.js",
"react",
"react-dom",
"remark-gfm",

View File

@@ -3,25 +3,20 @@
import { DOCUMENT } from "@angular/common";
import { Component, Inject, NgZone, OnDestroy, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { NavigationEnd, Router } from "@angular/router";
import * as jq from "jquery";
import { Router } from "@angular/router";
import { Subject, filter, firstValueFrom, map, takeUntil, timeout } from "rxjs";
import { CollectionService } from "@bitwarden/admin-console/common";
import { DeviceTrustToastService } from "@bitwarden/angular/auth/services/device-trust-toast.service.abstraction";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
import { InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service";
import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service";
import { VaultTimeoutService } from "@bitwarden/common/key-management/vault-timeout";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -29,11 +24,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { NotificationsService } from "@bitwarden/common/platform/notifications";
import { StateEventRunnerService } from "@bitwarden/common/platform/state";
import { SyncService } from "@bitwarden/common/platform/sync";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
import { DialogService, ToastService } from "@bitwarden/components";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy";
import { KeyService, BiometricStateService } from "@bitwarden/key-management";
import { PolicyListService } from "./admin-console/core/policy-list.service";
@@ -69,8 +62,6 @@ export class AppComponent implements OnDestroy, OnInit {
@Inject(DOCUMENT) private document: Document,
private broadcasterService: BroadcasterService,
private folderService: InternalFolderService,
private syncService: SyncService,
private passwordGenerationService: PasswordGenerationServiceAbstraction,
private cipherService: CipherService,
private authService: AuthService,
private router: Router,
@@ -85,17 +76,13 @@ export class AppComponent implements OnDestroy, OnInit {
private notificationsService: NotificationsService,
private stateService: StateService,
private eventUploadService: EventUploadService,
private policyService: InternalPolicyService,
protected policyListService: PolicyListService,
private keyConnectorService: KeyConnectorService,
protected configService: ConfigService,
private dialogService: DialogService,
private biometricStateService: BiometricStateService,
private stateEventRunnerService: StateEventRunnerService,
private organizationService: InternalOrganizationServiceAbstraction,
private accountService: AccountService,
private apiService: ApiService,
private appIdService: AppIdService,
private processReloadService: ProcessReloadServiceAbstraction,
private deviceTrustToastService: DeviceTrustToastService,
) {
@@ -247,15 +234,6 @@ export class AppComponent implements OnDestroy, OnInit {
});
});
this.router.events.pipe(takeUntil(this.destroy$)).subscribe((event) => {
if (event instanceof NavigationEnd) {
const modals = Array.from(document.querySelectorAll(".modal"));
for (const modal of modals) {
(jq(modal) as any).modal("hide");
}
}
});
this.policyListService.addPolicies([
new TwoFactorAuthenticationPolicy(),
new MasterPasswordPolicy(),

View File

@@ -26,7 +26,6 @@ import {
WINDOW,
} from "@bitwarden/angular/services/injection-tokens";
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/services/modal.service";
import {
RegistrationFinishService as RegistrationFinishServiceAbstraction,
LoginComponentService,
@@ -136,7 +135,6 @@ import { WebStorageServiceProvider } from "../platform/web-storage-service.provi
import { EventService } from "./event.service";
import { InitService } from "./init.service";
import { ENV_URLS } from "./injection-tokens";
import { ModalService } from "./modal.service";
import { RouterService } from "./router.service";
import { WebPlatformUtilsService } from "./web-platform-utils.service";
@@ -195,11 +193,6 @@ const safeProviders: SafeProvider[] = [
useClass: WebPlatformUtilsService,
useAngularDecorators: true,
}),
safeProvider({
provide: ModalServiceAbstraction,
useClass: ModalService,
useAngularDecorators: true,
}),
safeProvider({
provide: FileDownloadService,
useClass: WebFileDownloadService,

View File

@@ -1,56 +0,0 @@
import { Injectable, Injector } from "@angular/core";
import * as jq from "jquery";
import { first } from "rxjs/operators";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { ModalService as BaseModalService } from "@bitwarden/angular/services/modal.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
@Injectable()
export class ModalService extends BaseModalService {
el: any = null;
modalOpen = false;
constructor(
injector: Injector,
private messagingService: MessagingService,
) {
super(injector);
}
protected setupHandlers(modalRef: ModalRef) {
modalRef.onCreated.pipe(first()).subscribe(() => {
const modals = Array.from(document.querySelectorAll(".modal"));
if (modals.length > 0) {
this.el = jq(modals[0]);
this.el.modal("show");
this.el.on("show.bs.modal", () => {
modalRef.show();
this.messagingService.send("modalShow");
});
this.el.on("shown.bs.modal", () => {
modalRef.shown();
this.messagingService.send("modalShown");
if (!Utils.isMobileBrowser) {
this.el.find("*[appAutoFocus]").focus();
}
});
this.el.on("hide.bs.modal", () => {
this.messagingService.send("modalClose");
});
this.el.on("hidden.bs.modal", () => {
modalRef.closed();
this.messagingService.send("modalClosed");
});
}
});
modalRef.onClose.pipe(first()).subscribe(() => {
if (this.el != null) {
this.el.modal("hide");
}
});
}
}

View File

@@ -1,10 +1,6 @@
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import "bootstrap";
import "jquery";
import "popper.js";
import { AppModule } from "./app/app.module";
if (process.env.NODE_ENV === "production") {

View File

@@ -1,10 +1,6 @@
import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import "bootstrap";
import "jquery";
import "popper.js";
import { AppModule } from "./app/app.module";
if (process.env.NODE_ENV === "production") {

24
package-lock.json generated
View File

@@ -45,7 +45,6 @@
"form-data": "4.0.1",
"https-proxy-agent": "7.0.6",
"inquirer": "8.2.6",
"jquery": "3.7.1",
"jsdom": "26.1.0",
"jszip": "3.10.1",
"koa": "2.16.1",
@@ -62,7 +61,6 @@
"open": "8.4.2",
"papaparse": "5.5.2",
"patch-package": "8.0.0",
"popper.js": "1.16.1",
"proper-lockfile": "4.1.2",
"qrcode-parser": "2.1.3",
"qrious": "4.0.2",
@@ -102,7 +100,6 @@
"@types/firefox-webext-browser": "120.0.4",
"@types/inquirer": "8.2.10",
"@types/jest": "29.5.12",
"@types/jquery": "3.5.32",
"@types/jsdom": "21.1.7",
"@types/koa": "2.15.0",
"@types/koa__multer": "2.0.7",
@@ -11723,16 +11720,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/jquery": {
"version": "3.5.32",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
"integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/sizzle": "*"
}
},
"node_modules/@types/jsdom": {
"version": "21.1.7",
"resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz",
@@ -12099,13 +12086,6 @@
"@types/send": "*"
}
},
"node_modules/@types/sizzle": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
"integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/sockjs": {
"version": "0.3.36",
"resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz",
@@ -25233,7 +25213,8 @@
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/js-tokens": {
"version": "4.0.0",
@@ -31666,6 +31647,7 @@
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
"deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
"license": "MIT",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"

View File

@@ -66,7 +66,6 @@
"@types/firefox-webext-browser": "120.0.4",
"@types/inquirer": "8.2.10",
"@types/jest": "29.5.12",
"@types/jquery": "3.5.32",
"@types/jsdom": "21.1.7",
"@types/koa": "2.15.0",
"@types/koa__multer": "2.0.7",
@@ -181,7 +180,6 @@
"form-data": "4.0.1",
"https-proxy-agent": "7.0.6",
"inquirer": "8.2.6",
"jquery": "3.7.1",
"jsdom": "26.1.0",
"jszip": "3.10.1",
"koa": "2.16.1",
@@ -198,7 +196,6 @@
"open": "8.4.2",
"papaparse": "5.5.2",
"patch-package": "8.0.0",
"popper.js": "1.16.1",
"proper-lockfile": "4.1.2",
"qrcode-parser": "2.1.3",
"qrious": "4.0.2",