Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/vue-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,25 @@ export const createIonRouter = (
routeInfo.tab
);
routeInfo.pushedByRoute = lastRoute?.pushedByRoute;
} else if (
routeInfo.routerAction === "push" &&
routeInfo.routerDirection === "none" &&
routeInfo.tab === leavingLocationInfo.tab
) {
/**
* Same-tab push with direction "none" still needs pushedByRoute so
* ion-back-button uses history instead of falling back to defaultHref.
* Cross-tab pushes hit the branch above.
*
* Skip when the candidate equals the current pathname (e.g. /a?x=1 ->
* /a?x=2) to avoid a self-loop on back. Same guard as the replace
* branch below.
*/
const candidate = leavingLocationInfo.pathname;
routeInfo.pushedByRoute =
candidate !== "" && candidate !== routeInfo.pathname
? candidate
: undefined;
} else if (routeInfo.routerAction === "replace") {
/**
* When replacing a route, we want to make sure we select the current route
Expand Down
12 changes: 12 additions & 0 deletions packages/vue/test/base/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ const routes: Array<RouteRecordRaw> = [
path: '/default-href',
component: () => import('@/views/DefaultHref.vue')
},
{
path: '/direction-none-back/a',
component: () => import('@/views/DirectionNoneBackA.vue')
},
{
path: '/direction-none-back/b',
component: () => import('@/views/DirectionNoneBackB.vue')
},
{
path: '/direction-none-back/fallback',
component: () => import('@/views/DirectionNoneBackFallback.vue')
},
{
path: '/routing',
component: () => import('@/views/Routing.vue')
Expand Down
40 changes: 40 additions & 0 deletions packages/vue/test/base/src/views/DirectionNoneBackA.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<ion-page data-pageid="direction-none-page-a">
<ion-header>
<ion-toolbar>
<ion-title>Page A</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-button id="go-forward" router-link="/direction-none-back/b">
Go to B (forward)
</ion-button>
<ion-button id="go-none" router-link="/direction-none-back/b" router-direction="none">
Go to B (none)
</ion-button>
</ion-content>
</ion-page>
</template>

<script lang="ts">
import {
IonButton,
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
} from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
components: {
IonButton,
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
}
});
</script>
40 changes: 40 additions & 0 deletions packages/vue/test/base/src/views/DirectionNoneBackB.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<ion-page data-pageid="direction-none-page-b">
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-back-button default-href="/direction-none-back/fallback"></ion-back-button>
</ion-buttons>
<ion-title>Page B</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<p>Page B content</p>
</ion-content>
</ion-page>
</template>

<script lang="ts">
import {
IonBackButton,
IonButtons,
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
} from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
components: {
IonBackButton,
IonButtons,
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
}
});
</script>
33 changes: 33 additions & 0 deletions packages/vue/test/base/src/views/DirectionNoneBackFallback.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<ion-page data-pageid="direction-none-page-fallback">
<ion-header>
<ion-toolbar>
<ion-title>Fallback (defaultHref)</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<p>This page should NOT be reached via back button if history exists</p>
</ion-content>
</ion-page>
</template>

<script lang="ts">
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
} from '@ionic/vue';
import { defineComponent } from 'vue';

export default defineComponent({
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar
}
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { test, expect } from './utils/test-base';
import { ionPageVisible, ionPageDoesNotExist, ionBackClick } from './utils/test-utils';

/**
* Tests that ion-back-button works correctly after navigating with
* router-direction="none". The back button should use history to determine
* the previous page, not fall back to defaultHref.
*
* @see https://github.com/ionic-team/ionic-framework/issues/24074
*/
test.describe('router-direction="none" Back Button', () => {
test('back button should return to Page A after navigating with direction "forward"', async ({ page }) => {
await page.goto('/direction-none-back/a');
await ionPageVisible(page, 'direction-none-page-a');

await page.locator('ion-button#go-forward').click();
await ionPageVisible(page, 'direction-none-page-b');

await ionBackClick(page, 'direction-none-page-b');
await ionPageDoesNotExist(page, 'direction-none-page-fallback');
await ionPageVisible(page, 'direction-none-page-a');
expect(new URL(page.url()).pathname).toBe('/direction-none-back/a');
});

test('back button should return to Page A after navigating with direction "none"', async ({ page }) => {
await page.goto('/direction-none-back/a');
await ionPageVisible(page, 'direction-none-page-a');

await page.locator('ion-button#go-none').click();
await ionPageVisible(page, 'direction-none-page-b');

await ionBackClick(page, 'direction-none-page-b');
await ionPageDoesNotExist(page, 'direction-none-page-fallback');
await ionPageVisible(page, 'direction-none-page-a');
expect(new URL(page.url()).pathname).toBe('/direction-none-back/a');
});
});
Loading