diff --git a/packages/vue-router/src/locationHistory.ts b/packages/vue-router/src/locationHistory.ts index 3d242fe540..ac3d8ac6f6 100644 --- a/packages/vue-router/src/locationHistory.ts +++ b/packages/vue-router/src/locationHistory.ts @@ -105,11 +105,15 @@ export const createLocationHistory = () => { const size = () => locationHistory.length; - const updateByHistoryPosition = (routeInfo: RouteInfo) => { + const updateByHistoryPosition = (routeInfo: RouteInfo, updateEntries: boolean) => { const existingRouteIndex = locationHistory.findIndex(r => r.position === routeInfo.position); if (existingRouteIndex === -1) return; locationHistory[existingRouteIndex].pathname = routeInfo.pathname; + + if (updateEntries) { + locationHistory[existingRouteIndex].pushedByRoute = routeInfo.pushedByRoute; + } } /** diff --git a/packages/vue-router/src/router.ts b/packages/vue-router/src/router.ts index a8f968b53d..5d81b91756 100644 --- a/packages/vue-router/src/router.ts +++ b/packages/vue-router/src/router.ts @@ -275,7 +275,23 @@ export const createIonRouter = (opts: IonicVueRouterOptions, router: Router) => * new items within the stack. */ if (historySize > historyDiff && routeInfo.tab === undefined) { - locationHistory.updateByHistoryPosition(routeInfo); + /** + * When going from /a --> /a/1 --> /b, then going + * back to /a, then going /a --> /a/2 --> /b, clicking + * the ion-back-button should return us to /a/2, not /a/1. + * However, since the route entry for /b already exists, + * we need to update other information such as the "pushedByRoute" + * so we know which route pushed this new route. + * + * However, when using router.go with a stride of >1 or <-1, + * we should not update this additional information because + * we are traversing through the history, not pushing new states. + * Going from /a --> /b --> /c, then doing router.go(-2), then doing + * router.go(2) to go from /a --> /c should not update the route + * listing to say that /c was pushed by /a. + */ + const hasDeltaStride = delta !== undefined && Math.abs(delta) !== 1; + locationHistory.updateByHistoryPosition(routeInfo, !hasDeltaStride); } else { locationHistory.add(routeInfo); } diff --git a/packages/vue/test-app/tests/e2e/specs/routing.js b/packages/vue/test-app/tests/e2e/specs/routing.js index fc762a8eb5..82b5bcb1e2 100644 --- a/packages/vue/test-app/tests/e2e/specs/routing.js +++ b/packages/vue/test-app/tests/e2e/specs/routing.js @@ -316,6 +316,51 @@ describe('Routing', () => { cy.ionPageDoesNotExist('routing'); cy.ionPageDoesNotExist('routingparameter'); }) + + // Verifies fix for https://github.com/ionic-team/ionic-framework/issues/23987 + it('should choose correct view when navigating back', () => { + cy.visit('http://localhost:8080'); + + cy.routerPush('/routing'); + cy.ionPageVisible('routing'); + cy.ionPageHidden('home'); + + cy.routerPush('/routing/123/view'); + cy.ionPageVisible('routingparameterview'); + cy.ionPageHidden('routing'); + + cy.routerPush('/routing/child'); + cy.ionPageVisible('routingchild'); + cy.ionPageHidden('routing'); + + cy.ionBackClick('routingchild'); + cy.ionPageVisible('routingparameterview'); + cy.ionPageDoesNotExist('routingchild'); + + cy.ionBackClick('routingparameterview'); + cy.ionPageVisible('routing'); + cy.ionPageDoesNotExist('routingparameterview'); + + cy.ionBackClick('routing'); + cy.ionPageVisible('home'); + cy.ionPageDoesNotExist('routing'); + + cy.routerPush('/routing'); + cy.ionPageVisible('routing'); + cy.ionPageHidden('home'); + + cy.routerPush('/routing/456/view'); + cy.ionPageVisible('routingparameterview'); + cy.ionPageHidden('routing'); + + cy.routerPush('/routing/child'); + cy.ionPageVisible('routingchild'); + cy.ionPageHidden('routing'); + + cy.ionBackClick('routingchild'); + cy.ionPageVisible('routingparameterview'); + cy.ionPageDoesNotExist('routingchild'); + }) }); describe('Routing - Swipe to Go Back', () => {