diff --git a/apps/browser/src/platform/polyfills/zone-patch-chrome-runtime.ts b/apps/browser/src/platform/polyfills/zone-patch-chrome-runtime.ts new file mode 100644 index 0000000000..fa731840f8 --- /dev/null +++ b/apps/browser/src/platform/polyfills/zone-patch-chrome-runtime.ts @@ -0,0 +1,36 @@ +/** + * Monkey patch `chrome.runtime.onMessage` event listeners to run in the Angular zone. + */ +Zone.__load_patch("ChromeRuntimeOnMessage", (global: any, Zone: ZoneType, api: _ZonePrivate) => { + const onMessage = global.chrome.runtime.onMessage; + if (typeof global?.chrome?.runtime?.onMessage === "undefined") { + return; + } + + // eslint-disable-next-line @typescript-eslint/ban-types + api.patchMethod(onMessage, "addListener", (delegate: Function) => (self: any, 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 delegate.call(self, wrapperedCallback); + } else { + return delegate.apply(self, args); + } + }); + + // eslint-disable-next-line @typescript-eslint/ban-types + api.patchMethod(onMessage, "removeListener", (delegate: Function) => (self: any, args: any[]) => { + const callback = args.length > 0 ? args[0] : null; + if (typeof callback === "function") { + const wrapperedCallback = callback[api.symbol("chromeRuntimeOnMessageCallback")]; + if (wrapperedCallback) { + return delegate.call(self, wrapperedCallback); + } else { + return delegate.apply(self, args); + } + } else { + return delegate.apply(self, args); + } + }); +}); diff --git a/apps/browser/src/popup/polyfills.ts b/apps/browser/src/popup/polyfills.ts index 8edc909639..e41e960a8d 100644 --- a/apps/browser/src/popup/polyfills.ts +++ b/apps/browser/src/popup/polyfills.ts @@ -1,3 +1,5 @@ import "core-js/stable"; import "date-input-polyfill"; import "zone.js"; + +import "../platform/polyfills/zone-patch-chrome-runtime";