mirror of
https://github.com/bitwarden/browser
synced 2025-01-29 20:50:58 +01:00
[PM-4401] Re-add manual ngZone.run execution (#6647)
* [PM-4401] feat: add browser messaging api service * [PM-4401] feat: use new service * [PM-4401] chore: rename to `ZonedMessageListenerService` * [PM-4401] chore: remove polyfill
This commit is contained in:
parent
8dc81b603d
commit
c1494b8494
@ -0,0 +1,21 @@
|
||||
import { NgZone } from "@angular/core";
|
||||
import { MonoTypeOperatorFunction, Observable } from "rxjs";
|
||||
|
||||
export function runInsideAngular<T>(ngZone: NgZone): MonoTypeOperatorFunction<T> {
|
||||
return (source: Observable<T>) =>
|
||||
new Observable<T>((subscriber) => {
|
||||
const subscription = source.subscribe({
|
||||
next(value) {
|
||||
ngZone.run(() => subscriber.next(value));
|
||||
},
|
||||
error(error: unknown) {
|
||||
ngZone.run(() => subscriber.error(error));
|
||||
},
|
||||
complete() {
|
||||
ngZone.run(() => subscriber.complete());
|
||||
},
|
||||
});
|
||||
|
||||
return () => subscription.unsubscribe();
|
||||
});
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
import { Injectable, NgZone } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
|
||||
import { BrowserApi } from "./browser-api";
|
||||
import { runInsideAngular } from "./run-inside-angular.operator";
|
||||
|
||||
/**
|
||||
* This service is used for listening to messages from the background script.
|
||||
* It automatically runs all callbacks inside the Angular zone.
|
||||
* This should be used instead of `BrowserApi.messageListener` in all popup-components.
|
||||
* Not needed for services running in the background script.
|
||||
*/
|
||||
@Injectable({ providedIn: "root" })
|
||||
export class ZonedMessageListenerService {
|
||||
constructor(private ngZone: NgZone) {}
|
||||
|
||||
messageListener(
|
||||
name: string,
|
||||
callback: (
|
||||
message: any,
|
||||
sender: chrome.runtime.MessageSender,
|
||||
sendResponse: any
|
||||
) => boolean | void
|
||||
) {
|
||||
BrowserApi.messageListener(name, (message, sender, sendResponse) => {
|
||||
return this.ngZone.run(() => callback(message, sender, sendResponse));
|
||||
});
|
||||
}
|
||||
|
||||
messageListener$(): Observable<unknown> {
|
||||
return BrowserApi.messageListener$().pipe(runInsideAngular(this.ngZone));
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* Monkey patch `chrome.runtime.onMessage` event listeners to run in the Angular zone.
|
||||
*/
|
||||
Zone.__load_patch("ChromeRuntimeOnMessage", (global: any, Zone: ZoneType, api: _ZonePrivate) => {
|
||||
if (typeof global?.chrome?.runtime?.onMessage === "undefined") {
|
||||
return;
|
||||
}
|
||||
const onMessage = global.chrome.runtime.onMessage;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const nativeAddListener = onMessage.addListener as Function;
|
||||
api.ObjectDefineProperty(chrome.runtime.onMessage, "addListener", {
|
||||
value: function (...args: any[]) {
|
||||
const callback = args.length > 0 ? args[0] : null;
|
||||
if (typeof callback === "function") {
|
||||
const wrapperedCallback = Zone.current.wrap(callback, "ChromeRuntimeOnMessage");
|
||||
callback[api.symbol("chromeRuntimeOnMessageCallback")] = wrapperedCallback;
|
||||
return nativeAddListener.call(onMessage, wrapperedCallback);
|
||||
} else {
|
||||
return nativeAddListener.apply(onMessage, args);
|
||||
}
|
||||
},
|
||||
writable: false,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
const nativeRemoveListener = onMessage.removeListener as Function;
|
||||
api.ObjectDefineProperty(chrome.runtime.onMessage, "removeListener", {
|
||||
value: function (...args: any[]) {
|
||||
const callback = args.length > 0 ? args[0] : null;
|
||||
if (typeof callback === "function") {
|
||||
const wrapperedCallback = callback[api.symbol("chromeRuntimeOnMessageCallback")];
|
||||
if (wrapperedCallback) {
|
||||
return nativeRemoveListener.call(onMessage, wrapperedCallback);
|
||||
} else {
|
||||
return nativeRemoveListener.apply(onMessage, args);
|
||||
}
|
||||
} else {
|
||||
return nativeRemoveListener.apply(onMessage, args);
|
||||
}
|
||||
},
|
||||
writable: false,
|
||||
});
|
||||
});
|
@ -19,6 +19,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
|
||||
import { DialogService, SimpleDialogOptions } from "@bitwarden/components";
|
||||
|
||||
import { BrowserApi } from "../platform/browser/browser-api";
|
||||
import { ZonedMessageListenerService } from "../platform/browser/zoned-message-listener.service";
|
||||
import { BrowserStateService } from "../platform/services/abstractions/browser-state.service";
|
||||
|
||||
import { routerTransition } from "./app-routing.animations";
|
||||
@ -50,7 +51,8 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
private ngZone: NgZone,
|
||||
private sanitizer: DomSanitizer,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private dialogService: DialogService
|
||||
private dialogService: DialogService,
|
||||
private browserMessagingApi: ZonedMessageListenerService
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
@ -128,7 +130,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
|
||||
(window as any).bitwardenPopupMainMessageListener = bitwardenPopupMainMessageListener;
|
||||
BrowserApi.messageListener("app.component", bitwardenPopupMainMessageListener);
|
||||
this.browserMessagingApi.messageListener("app.component", bitwardenPopupMainMessageListener);
|
||||
|
||||
// eslint-disable-next-line rxjs/no-async-subscribe
|
||||
this.router.events.pipe(takeUntil(this.destroy$)).subscribe(async (event) => {
|
||||
|
@ -1,4 +1,2 @@
|
||||
import "core-js/stable";
|
||||
import "zone.js";
|
||||
|
||||
import "../platform/polyfills/zone-patch-chrome-runtime";
|
||||
|
@ -30,7 +30,7 @@ import { SecureNoteView } from "@bitwarden/common/vault/models/view/secure-note.
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { PasswordRepromptService } from "@bitwarden/vault";
|
||||
|
||||
import { BrowserApi } from "../../../../platform/browser/browser-api";
|
||||
import { ZonedMessageListenerService } from "../../../../platform/browser/zoned-message-listener.service";
|
||||
import {
|
||||
BrowserFido2Message,
|
||||
BrowserFido2UserInterfaceSession,
|
||||
@ -78,7 +78,8 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
private settingsService: SettingsService,
|
||||
private searchService: SearchService,
|
||||
private logService: LogService,
|
||||
private dialogService: DialogService
|
||||
private dialogService: DialogService,
|
||||
private browserMessagingApi: ZonedMessageListenerService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@ -93,7 +94,10 @@ export class Fido2Component implements OnInit, OnDestroy {
|
||||
}))
|
||||
);
|
||||
|
||||
combineLatest([queryParams$, BrowserApi.messageListener$() as Observable<BrowserFido2Message>])
|
||||
combineLatest([
|
||||
queryParams$,
|
||||
this.browserMessagingApi.messageListener$() as Observable<BrowserFido2Message>,
|
||||
])
|
||||
.pipe(
|
||||
concatMap(async ([queryParams, message]) => {
|
||||
this.sessionId = queryParams.sessionId;
|
||||
|
Loading…
x
Reference in New Issue
Block a user