From 9b00e20746a192b1d4430f6786af472422762bc9 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Sat, 16 Sep 2023 18:05:03 +0200 Subject: [PATCH 01/10] fix(angular): fix navigation stack when using browser back and forward button fix(angular): respect direction set via the NavController fix(angular): adapt tests fix(angular): fixes --- .../directives/navigation/stack-controller.ts | 66 ++++++++++++++----- .../src/directives/navigation/stack-utils.ts | 2 + .../angular/src/providers/nav-controller.ts | 9 ++- .../test/base/e2e/src/router-link.spec.ts | 6 +- 4 files changed, 63 insertions(+), 20 deletions(-) diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 673ff34d020..6caf1dd0e3a 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -1,7 +1,7 @@ import { Location } from '@angular/common'; import { ComponentRef, NgZone } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { AnimationBuilder, RouterDirection } from '@ionic/core'; +import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core'; import { bindLifecycleEvents } from '../../providers/angular-delegate'; import { NavController } from '../../providers/nav-controller'; @@ -62,14 +62,8 @@ export class StackController { } setActive(enteringView: RouteView): Promise { - const consumeResult = this.navCtrl.consumeTransition(); + const { isDirectionBasedOnNavigationIds, ...consumeResult } = this.navCtrl.consumeTransition(); let { direction, animation, animationBuilder } = consumeResult; - const leavingView = this.activeView; - const tabSwitch = isTabSwitch(enteringView, leavingView); - if (tabSwitch) { - direction = 'back'; - animation = undefined; - } const viewsSnapshot = this.views.slice(); @@ -87,25 +81,65 @@ export class StackController { } /** - * If the navigation action - * sets `replaceUrl: true` - * then we need to make sure - * we remove the last item - * from our views stack + * If the navigation action sets `replaceUrl: true` then we need to make sure + * we remove the last item from our views stack */ - if (currentNavigation?.extras?.replaceUrl) { + if (currentNavigation?.extras?.replaceUrl && currentNavigation?.trigger !== 'popstate') { if (this.views.length > 0) { this.views.splice(-1, 1); } } - const reused = this.views.includes(enteringView); + // determine direction based on the order of the views in the stack + const leavingView = this.activeView; + const isEnteringViewReused = this.views.includes(enteringView); + const leavingViewIndex = leavingView ? this.views.indexOf(leavingView) : -1; + const enteringViewIndex = isEnteringViewReused ? this.views.indexOf(enteringView) : this.views.length; + const suggestedDirectionBasedOnStackOrder: NavDirection | undefined = + leavingViewIndex === -1 ? undefined : enteringViewIndex < leavingViewIndex ? 'back' : 'forward'; + + /** + * The user triggered a back navigation on a page that was navigated to with root. In this case, the new page + * becomes the root and the leavingView is removed. + * + * This can happen when e.g.: + * - using the NavController's navigateBack on a root page + * - navigating to a page with navigateRoot and then using the browser back button + */ + if ( + direction === 'back' && + isDirectionBasedOnNavigationIds && + leavingView?.root && + currentNavigation?.trigger === 'popstate' + ) { + if (leavingViewIndex >= 0) { + this.views.splice(leavingViewIndex, 1); + } + } + + /** + * direction based on stack order takes precedence over direction based on navigation ids + * + * only applied if the user did not explicitly set the direction + * (e.g. via the NavController, routerLink directive etc.) + */ + if (isDirectionBasedOnNavigationIds && suggestedDirectionBasedOnStackOrder) { + direction = suggestedDirectionBasedOnStackOrder; + animation = suggestedDirectionBasedOnStackOrder; + } + + const tabSwitch = isTabSwitch(enteringView, leavingView); + if (tabSwitch) { + direction = 'back'; + animation = undefined; + } + const views = this.insertView(enteringView, direction); // Trigger change detection before transition starts // This will call ngOnInit() the first time too, just after the view // was attached to the dom, but BEFORE the transition starts - if (!reused) { + if (!isEnteringViewReused) { enteringView.ref.changeDetectorRef.detectChanges(); } diff --git a/packages/angular/src/directives/navigation/stack-utils.ts b/packages/angular/src/directives/navigation/stack-utils.ts index dda4ecac7bd..f6e05af9e4d 100644 --- a/packages/angular/src/directives/navigation/stack-utils.ts +++ b/packages/angular/src/directives/navigation/stack-utils.ts @@ -14,6 +14,7 @@ export const insertView = (views: RouteView[], view: RouteView, direction: Route const setRoot = (views: RouteView[], view: RouteView) => { views = views.filter((v) => v.stackId !== view.stackId); + view.root = true; views.push(view); return views; }; @@ -110,4 +111,5 @@ export interface RouteView { savedExtras?: NavigationExtras; unlistenEvents: () => void; animationBuilder?: AnimationBuilder; + root?: boolean; } diff --git a/packages/angular/src/providers/nav-controller.ts b/packages/angular/src/providers/nav-controller.ts index 101967f0f2f..307f6cb8425 100644 --- a/packages/angular/src/providers/nav-controller.ts +++ b/packages/angular/src/providers/nav-controller.ts @@ -37,10 +37,11 @@ export class NavController { if (router) { router.events.subscribe((ev) => { if (ev instanceof NavigationStart) { + // restoredState is set if the browser back/forward button is used const id = ev.restoredState ? ev.restoredState.navigationId : ev.id; this.guessDirection = id < this.lastNavId ? 'back' : 'forward'; - this.guessAnimation = !ev.restoredState ? this.guessDirection : undefined; - this.lastNavId = this.guessDirection === 'forward' ? ev.id : id; + this.guessAnimation = this.guessDirection; + this.lastNavId = id; } }); } @@ -180,11 +181,14 @@ export class NavController { direction: RouterDirection; animation: NavDirection | undefined; animationBuilder: AnimationBuilder | undefined; + isDirectionBasedOnNavigationIds: boolean; } { let direction: RouterDirection = 'root'; let animation: NavDirection | undefined; const animationBuilder = this.animationBuilder; + const isDirectionBasedOnNavigationIds = this.direction === 'auto'; + if (this.direction === 'auto') { direction = this.guessDirection; animation = this.guessAnimation; @@ -200,6 +204,7 @@ export class NavController { direction, animation, animationBuilder, + isDirectionBasedOnNavigationIds, }; } diff --git a/packages/angular/test/base/e2e/src/router-link.spec.ts b/packages/angular/test/base/e2e/src/router-link.spec.ts index ba169906adf..69174e1f8f5 100644 --- a/packages/angular/test/base/e2e/src/router-link.spec.ts +++ b/packages/angular/test/base/e2e/src/router-link.spec.ts @@ -113,6 +113,7 @@ describe('Router Link', () => { describe('back', () => { it('should go back with ion-button[routerLink][routerDirection=back]', () => { cy.get('#routerLink-back').click(); + testBack(); }); it('should go back with a[routerLink][routerDirection=back]', () => { @@ -138,6 +139,7 @@ function testForward() { cy.get('app-router-link-page #canGoBack').should('have.text', 'true'); cy.go('back'); + cy.wait(500); cy.testStack('ion-router-outlet', ['app-router-link']); cy.testLifeCycle('app-router-link', { ionViewWillEnter: 2, @@ -159,7 +161,7 @@ function testRoot() { cy.get('app-router-link-page #canGoBack').should('have.text', 'false'); cy.go('back'); - cy.wait(100); + cy.wait(500); cy.testStack('ion-router-outlet', ['app-router-link']); cy.testLifeCycle('app-router-link', { ionViewWillEnter: 1, @@ -181,7 +183,7 @@ function testBack() { cy.get('app-router-link-page #canGoBack').should('have.text', 'false'); cy.go('back'); - cy.wait(100); + cy.wait(500); cy.testStack('ion-router-outlet', ['app-router-link']); cy.testLifeCycle('app-router-link', { ionViewWillEnter: 1, From 64e0b4439ce015a656894fe29eb17cf808654306 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Sat, 16 Sep 2023 18:15:43 +0200 Subject: [PATCH 02/10] fix(angular): remove legacy code for Angular < 7.2.0 --- .../src/directives/navigation/stack-controller.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 6caf1dd0e3a..77b70c3209c 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -67,18 +67,7 @@ export class StackController { const viewsSnapshot = this.views.slice(); - let currentNavigation; - - const router = this.router as any; - - // Angular >= 7.2.0 - if (router.getCurrentNavigation) { - currentNavigation = router.getCurrentNavigation(); - - // Angular < 7.2.0 - } else if (router.navigations?.value) { - currentNavigation = router.navigations.value; - } + const currentNavigation = this.router.getCurrentNavigation(); /** * If the navigation action sets `replaceUrl: true` then we need to make sure From 9846503a47a0a6f0318354e8c8c5e646e558589b Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Sat, 16 Sep 2023 18:41:16 +0200 Subject: [PATCH 03/10] fix(angular): update comment --- .../angular/src/directives/navigation/stack-controller.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 77b70c3209c..059f7c545ae 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -91,9 +91,7 @@ export class StackController { * The user triggered a back navigation on a page that was navigated to with root. In this case, the new page * becomes the root and the leavingView is removed. * - * This can happen when e.g.: - * - using the NavController's navigateBack on a root page - * - navigating to a page with navigateRoot and then using the browser back button + * This can happen e.g. when navigating to a page with navigateRoot and then using the browser back button */ if ( direction === 'back' && From b7d25eab796bd1f5ed8fbfb4f5e8107fc13a9ff2 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Fri, 6 Oct 2023 07:39:19 +0200 Subject: [PATCH 04/10] revert: revert changes regarding navigation stack --- .../directives/navigation/stack-controller.ts | 64 +++++-------------- .../src/directives/navigation/stack-utils.ts | 2 - .../angular/src/providers/nav-controller.ts | 8 +-- 3 files changed, 18 insertions(+), 56 deletions(-) diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 059f7c545ae..71f2dc6301b 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -1,7 +1,7 @@ import { Location } from '@angular/common'; import { ComponentRef, NgZone } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { AnimationBuilder, NavDirection, RouterDirection } from '@ionic/core'; +import { AnimationBuilder, RouterDirection } from '@ionic/core'; import { bindLifecycleEvents } from '../../providers/angular-delegate'; import { NavController } from '../../providers/nav-controller'; @@ -62,71 +62,39 @@ export class StackController { } setActive(enteringView: RouteView): Promise { - const { isDirectionBasedOnNavigationIds, ...consumeResult } = this.navCtrl.consumeTransition(); + const consumeResult = this.navCtrl.consumeTransition(); let { direction, animation, animationBuilder } = consumeResult; + const leavingView = this.activeView; + const tabSwitch = isTabSwitch(enteringView, leavingView); + if (tabSwitch) { + direction = 'back'; + animation = undefined; + } const viewsSnapshot = this.views.slice(); const currentNavigation = this.router.getCurrentNavigation(); /** - * If the navigation action sets `replaceUrl: true` then we need to make sure - * we remove the last item from our views stack + * If the navigation action + * sets `replaceUrl: true` + * then we need to make sure + * we remove the last item + * from our views stack */ - if (currentNavigation?.extras?.replaceUrl && currentNavigation?.trigger !== 'popstate') { + if (currentNavigation?.extras?.replaceUrl) { if (this.views.length > 0) { this.views.splice(-1, 1); } } - // determine direction based on the order of the views in the stack - const leavingView = this.activeView; - const isEnteringViewReused = this.views.includes(enteringView); - const leavingViewIndex = leavingView ? this.views.indexOf(leavingView) : -1; - const enteringViewIndex = isEnteringViewReused ? this.views.indexOf(enteringView) : this.views.length; - const suggestedDirectionBasedOnStackOrder: NavDirection | undefined = - leavingViewIndex === -1 ? undefined : enteringViewIndex < leavingViewIndex ? 'back' : 'forward'; - - /** - * The user triggered a back navigation on a page that was navigated to with root. In this case, the new page - * becomes the root and the leavingView is removed. - * - * This can happen e.g. when navigating to a page with navigateRoot and then using the browser back button - */ - if ( - direction === 'back' && - isDirectionBasedOnNavigationIds && - leavingView?.root && - currentNavigation?.trigger === 'popstate' - ) { - if (leavingViewIndex >= 0) { - this.views.splice(leavingViewIndex, 1); - } - } - - /** - * direction based on stack order takes precedence over direction based on navigation ids - * - * only applied if the user did not explicitly set the direction - * (e.g. via the NavController, routerLink directive etc.) - */ - if (isDirectionBasedOnNavigationIds && suggestedDirectionBasedOnStackOrder) { - direction = suggestedDirectionBasedOnStackOrder; - animation = suggestedDirectionBasedOnStackOrder; - } - - const tabSwitch = isTabSwitch(enteringView, leavingView); - if (tabSwitch) { - direction = 'back'; - animation = undefined; - } - + const reused = this.views.includes(enteringView); const views = this.insertView(enteringView, direction); // Trigger change detection before transition starts // This will call ngOnInit() the first time too, just after the view // was attached to the dom, but BEFORE the transition starts - if (!isEnteringViewReused) { + if (!reused) { enteringView.ref.changeDetectorRef.detectChanges(); } diff --git a/packages/angular/src/directives/navigation/stack-utils.ts b/packages/angular/src/directives/navigation/stack-utils.ts index f6e05af9e4d..dda4ecac7bd 100644 --- a/packages/angular/src/directives/navigation/stack-utils.ts +++ b/packages/angular/src/directives/navigation/stack-utils.ts @@ -14,7 +14,6 @@ export const insertView = (views: RouteView[], view: RouteView, direction: Route const setRoot = (views: RouteView[], view: RouteView) => { views = views.filter((v) => v.stackId !== view.stackId); - view.root = true; views.push(view); return views; }; @@ -111,5 +110,4 @@ export interface RouteView { savedExtras?: NavigationExtras; unlistenEvents: () => void; animationBuilder?: AnimationBuilder; - root?: boolean; } diff --git a/packages/angular/src/providers/nav-controller.ts b/packages/angular/src/providers/nav-controller.ts index 307f6cb8425..36880f84608 100644 --- a/packages/angular/src/providers/nav-controller.ts +++ b/packages/angular/src/providers/nav-controller.ts @@ -40,8 +40,8 @@ export class NavController { // restoredState is set if the browser back/forward button is used const id = ev.restoredState ? ev.restoredState.navigationId : ev.id; this.guessDirection = id < this.lastNavId ? 'back' : 'forward'; - this.guessAnimation = this.guessDirection; - this.lastNavId = id; + this.guessAnimation = !ev.restoredState ? this.guessDirection : undefined; + this.lastNavId = this.guessDirection === 'forward' ? ev.id : id; } }); } @@ -181,14 +181,11 @@ export class NavController { direction: RouterDirection; animation: NavDirection | undefined; animationBuilder: AnimationBuilder | undefined; - isDirectionBasedOnNavigationIds: boolean; } { let direction: RouterDirection = 'root'; let animation: NavDirection | undefined; const animationBuilder = this.animationBuilder; - const isDirectionBasedOnNavigationIds = this.direction === 'auto'; - if (this.direction === 'auto') { direction = this.guessDirection; animation = this.guessAnimation; @@ -204,7 +201,6 @@ export class NavController { direction, animation, animationBuilder, - isDirectionBasedOnNavigationIds, }; } From 887bad1bc2eb8016ca6724600263bced9f786911 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Fri, 6 Oct 2023 07:40:52 +0200 Subject: [PATCH 05/10] fix: apply fix for missing nav animation --- packages/angular/src/providers/nav-controller.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/angular/src/providers/nav-controller.ts b/packages/angular/src/providers/nav-controller.ts index 36880f84608..c26d0181c32 100644 --- a/packages/angular/src/providers/nav-controller.ts +++ b/packages/angular/src/providers/nav-controller.ts @@ -39,9 +39,8 @@ export class NavController { if (ev instanceof NavigationStart) { // restoredState is set if the browser back/forward button is used const id = ev.restoredState ? ev.restoredState.navigationId : ev.id; - this.guessDirection = id < this.lastNavId ? 'back' : 'forward'; - this.guessAnimation = !ev.restoredState ? this.guessDirection : undefined; - this.lastNavId = this.guessDirection === 'forward' ? ev.id : id; + this.guessDirection = this.guessAnimation = id < this.lastNavId ? 'back' : 'forward'; + this.lastNavId = id; } }); } From c36494b6114d78dd9acfb4daec0eea3b495ad1f2 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Fri, 6 Oct 2023 07:43:44 +0200 Subject: [PATCH 06/10] revert: revert changes in stack controller --- .../src/directives/navigation/stack-controller.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/angular/src/directives/navigation/stack-controller.ts b/packages/angular/src/directives/navigation/stack-controller.ts index 71f2dc6301b..673ff34d020 100644 --- a/packages/angular/src/directives/navigation/stack-controller.ts +++ b/packages/angular/src/directives/navigation/stack-controller.ts @@ -73,7 +73,18 @@ export class StackController { const viewsSnapshot = this.views.slice(); - const currentNavigation = this.router.getCurrentNavigation(); + let currentNavigation; + + const router = this.router as any; + + // Angular >= 7.2.0 + if (router.getCurrentNavigation) { + currentNavigation = router.getCurrentNavigation(); + + // Angular < 7.2.0 + } else if (router.navigations?.value) { + currentNavigation = router.navigations.value; + } /** * If the navigation action From bb91eb83603c59ccbe7c3a190d078951748490ed Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Fri, 6 Oct 2023 07:52:47 +0200 Subject: [PATCH 07/10] revert: revert changes for setting lastNavId --- packages/angular/src/providers/nav-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/src/providers/nav-controller.ts b/packages/angular/src/providers/nav-controller.ts index c26d0181c32..2db3dcbdce0 100644 --- a/packages/angular/src/providers/nav-controller.ts +++ b/packages/angular/src/providers/nav-controller.ts @@ -40,7 +40,7 @@ export class NavController { // restoredState is set if the browser back/forward button is used const id = ev.restoredState ? ev.restoredState.navigationId : ev.id; this.guessDirection = this.guessAnimation = id < this.lastNavId ? 'back' : 'forward'; - this.lastNavId = id; + this.lastNavId = this.guessDirection === 'forward' ? ev.id : id; } }); } From e36e5410735ccb971a98de3079930f34002d13c5 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Wed, 11 Oct 2023 07:18:51 +0200 Subject: [PATCH 08/10] revert: revert unnecessary change --- packages/angular/test/base/e2e/src/router-link.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/angular/test/base/e2e/src/router-link.spec.ts b/packages/angular/test/base/e2e/src/router-link.spec.ts index 69174e1f8f5..0c2a00ee8d5 100644 --- a/packages/angular/test/base/e2e/src/router-link.spec.ts +++ b/packages/angular/test/base/e2e/src/router-link.spec.ts @@ -113,7 +113,6 @@ describe('Router Link', () => { describe('back', () => { it('should go back with ion-button[routerLink][routerDirection=back]', () => { cy.get('#routerLink-back').click(); - testBack(); }); it('should go back with a[routerLink][routerDirection=back]', () => { From b5f487cee026814b6927c1c1628f9a7e2d54a2df Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Tue, 31 Oct 2023 15:31:59 +0100 Subject: [PATCH 09/10] fix: use root page transition when using root routerlink and browser back button --- .../directives/navigation/stack-controller.ts | 25 +++++++++++++------ .../src/directives/navigation/stack-utils.ts | 2 ++ .../base/e2e/src/lazy/router-link.spec.ts | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/angular/common/src/directives/navigation/stack-controller.ts b/packages/angular/common/src/directives/navigation/stack-controller.ts index 8241afa864f..437160ae24a 100644 --- a/packages/angular/common/src/directives/navigation/stack-controller.ts +++ b/packages/angular/common/src/directives/navigation/stack-controller.ts @@ -65,6 +65,8 @@ export class StackController { const consumeResult = this.navCtrl.consumeTransition(); let { direction, animation, animationBuilder } = consumeResult; const leavingView = this.activeView; + const leavingViewIndex = leavingView ? this.views.indexOf(leavingView) : -1; + const tabSwitch = isTabSwitch(enteringView, leavingView); if (tabSwitch) { direction = 'back'; @@ -73,17 +75,24 @@ export class StackController { const viewsSnapshot = this.views.slice(); - let currentNavigation; + const currentNavigation = this.router.getCurrentNavigation(); - const router = this.router as any; + /** + * The user triggered a back navigation on a page that was navigated to with root. In this case, the new page + * becomes the root and the leavingView is removed. + * + * This can happen e.g. when navigating to a page with navigateRoot and then using the browser back button + */ + const isPopStateTransitionFromRootPage = + direction === 'back' && leavingView?.root && currentNavigation?.trigger === 'popstate'; - // Angular >= 7.2.0 - if (router.getCurrentNavigation) { - currentNavigation = router.getCurrentNavigation(); + if (isPopStateTransitionFromRootPage) { + direction = 'root'; + animation = undefined; - // Angular < 7.2.0 - } else if (router.navigations?.value) { - currentNavigation = router.navigations.value; + if (leavingViewIndex >= 0) { + this.views.splice(leavingViewIndex, 1); + } } /** diff --git a/packages/angular/common/src/directives/navigation/stack-utils.ts b/packages/angular/common/src/directives/navigation/stack-utils.ts index 41203407599..44d05e1f2b9 100644 --- a/packages/angular/common/src/directives/navigation/stack-utils.ts +++ b/packages/angular/common/src/directives/navigation/stack-utils.ts @@ -14,6 +14,7 @@ export const insertView = (views: RouteView[], view: RouteView, direction: Route const setRoot = (views: RouteView[], view: RouteView) => { views = views.filter((v) => v.stackId !== view.stackId); + view.root = true; views.push(view); return views; }; @@ -110,4 +111,5 @@ export interface RouteView { savedExtras?: NavigationExtras; unlistenEvents: () => void; animationBuilder?: AnimationBuilder; + root?: boolean; } diff --git a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts index aeb31bf130e..51811cce583 100644 --- a/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts +++ b/packages/angular/test/base/e2e/src/lazy/router-link.spec.ts @@ -160,7 +160,7 @@ function testRoot() { cy.get('app-router-link-page #canGoBack').should('have.text', 'false'); cy.go('back'); - cy.wait(500); + cy.wait(100); cy.testStack('ion-router-outlet', ['app-router-link']); cy.testLifeCycle('app-router-link', { ionViewWillEnter: 1, From 9f2ea5ac8d844307d4c63393a373ab23b146be32 Mon Sep 17 00:00:00 2001 From: Philipp Heuer Date: Tue, 31 Oct 2023 15:43:40 +0100 Subject: [PATCH 10/10] chore: better semantic colocation of code --- .../directives/navigation/stack-controller.ts | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/angular/common/src/directives/navigation/stack-controller.ts b/packages/angular/common/src/directives/navigation/stack-controller.ts index 437160ae24a..d45e84fa168 100644 --- a/packages/angular/common/src/directives/navigation/stack-controller.ts +++ b/packages/angular/common/src/directives/navigation/stack-controller.ts @@ -67,16 +67,20 @@ export class StackController { const leavingView = this.activeView; const leavingViewIndex = leavingView ? this.views.indexOf(leavingView) : -1; - const tabSwitch = isTabSwitch(enteringView, leavingView); - if (tabSwitch) { - direction = 'back'; - animation = undefined; - } - const viewsSnapshot = this.views.slice(); const currentNavigation = this.router.getCurrentNavigation(); + /** + * If the navigation action sets `replaceUrl: true` then we need to make sure + * we remove the last item from our views stack + */ + if (currentNavigation?.extras?.replaceUrl && currentNavigation?.trigger !== 'popstate') { + if (this.views.length > 0) { + this.views.splice(-1, 1); + } + } + /** * The user triggered a back navigation on a page that was navigated to with root. In this case, the new page * becomes the root and the leavingView is removed. @@ -95,17 +99,10 @@ export class StackController { } } - /** - * If the navigation action - * sets `replaceUrl: true` - * then we need to make sure - * we remove the last item - * from our views stack - */ - if (currentNavigation?.extras?.replaceUrl) { - if (this.views.length > 0) { - this.views.splice(-1, 1); - } + const tabSwitch = isTabSwitch(enteringView, leavingView); + if (tabSwitch) { + direction = 'back'; + animation = undefined; } const reused = this.views.includes(enteringView);