1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-14 10:26:19 +01:00

[PM-10940] misc popout history cache bug fixes (#10619)

This commit is contained in:
Will Martin 2024-08-20 09:41:55 -04:00 committed by GitHub
parent 626f5abaa6
commit 59aa7ebc57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 8 deletions

View File

@ -7,7 +7,7 @@ import {
Router, Router,
UrlSerializer, UrlSerializer,
} from "@angular/router"; } from "@angular/router";
import { filter, first, firstValueFrom, map, Observable, of, switchMap } from "rxjs"; import { filter, first, firstValueFrom, map, Observable, of, switchMap, tap } from "rxjs";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@ -29,16 +29,25 @@ export class PopupRouterCacheService {
private state = inject(GlobalStateProvider).get(POPUP_ROUTE_HISTORY_KEY); private state = inject(GlobalStateProvider).get(POPUP_ROUTE_HISTORY_KEY);
private location = inject(Location); private location = inject(Location);
private hasNavigated = false;
constructor() { constructor() {
// init history with existing state // init history with existing state
this.history$() this.history$()
.pipe(first()) .pipe(first())
.subscribe((history) => history.forEach((location) => this.location.go(location))); .subscribe(
(history) =>
Array.isArray(history) && history.forEach((location) => this.location.go(location)),
);
// update state when route change occurs // update state when route change occurs
this.router.events this.router.events
.pipe( .pipe(
filter((event) => event instanceof NavigationEnd), filter((event) => event instanceof NavigationEnd),
tap(() => {
// `Location.back()` can now be called successfully
this.hasNavigated = true;
}),
filter((_event: NavigationEnd) => { filter((_event: NavigationEnd) => {
const state: ActivatedRouteSnapshot = this.router.routerState.snapshot.root; const state: ActivatedRouteSnapshot = this.router.routerState.snapshot.root;
@ -77,7 +86,7 @@ export class PopupRouterCacheService {
/** /**
* If in browser popup, push new route onto history stack * If in browser popup, push new route onto history stack
*/ */
private async push(url: string): Promise<boolean> { private async push(url: string) {
if (!BrowserPopupUtils.inPopup(window) || url === (await firstValueFrom(this.last$()))) { if (!BrowserPopupUtils.inPopup(window) || url === (await firstValueFrom(this.last$()))) {
return; return;
} }
@ -88,11 +97,10 @@ export class PopupRouterCacheService {
* Navigate back in history * Navigate back in history
*/ */
async back() { async back() {
await this.state.update((prevState) => prevState.slice(0, -1)); await this.state.update((prevState) => (prevState ? prevState.slice(0, -1) : []));
const url = this.router.url; if (this.hasNavigated) {
this.location.back(); this.location.back();
if (url !== this.router.url) {
return; return;
} }

View File

@ -65,6 +65,16 @@ describe("Popup router cache guard", () => {
expect(response).toBe(true); expect(response).toBe(true);
}); });
it("returns true if the history stack is null", async () => {
await service.setHistory(null);
const response = await firstValueFrom(
testBed.runInInjectionContext(() => popupRouterCacheGuard()),
);
expect(response).toBe(true);
});
it("redirects to the latest stored route", async () => { it("redirects to the latest stored route", async () => {
await router.navigate(["a"]); await router.navigate(["a"]);
await router.navigate(["b"]); await router.navigate(["b"]);

View File

@ -6,6 +6,7 @@ import {
GlobalStateProvider, GlobalStateProvider,
} from "@bitwarden/common/platform/state"; } from "@bitwarden/common/platform/state";
import { BrowserApi } from "../browser/browser-api";
import { fromChromeEvent } from "../browser/from-chrome-event"; import { fromChromeEvent } from "../browser/from-chrome-event";
const popupClosedPortName = "new_popup"; const popupClosedPortName = "new_popup";
@ -27,7 +28,7 @@ export class PopupViewCacheBackgroundService {
merge( merge(
// on tab changed, excluding extension tabs // on tab changed, excluding extension tabs
fromChromeEvent(chrome.tabs.onActivated).pipe( fromChromeEvent(chrome.tabs.onActivated).pipe(
switchMap(([tabInfo]) => chrome.tabs.get(tabInfo.tabId)), switchMap(([tabInfo]) => BrowserApi.getTab(tabInfo.tabId)),
map((tab) => tab.url || tab.pendingUrl), map((tab) => tab.url || tab.pendingUrl),
filter((url) => !url.startsWith(chrome.runtime.getURL(""))), filter((url) => !url.startsWith(chrome.runtime.getURL(""))),
), ),