fix(router): router push with relative path (#24719)

Resolves #24718
This commit is contained in:
Victor Berchet
2022-02-07 11:26:57 -08:00
committed by GitHub
parent 231d6df622
commit d40c0c3a09
5 changed files with 45 additions and 11 deletions

View File

@ -2197,11 +2197,11 @@ export namespace Components {
"navChanged": (direction: RouterDirection) => Promise<boolean>;
"printDebug": () => Promise<void>;
/**
* Navigate to the specified URL.
* @param url The url to navigate to.
* Navigate to the specified path.
* @param path The path to navigate to.
* @param direction The direction of the animation. Defaults to `"forward"`.
*/
"push": (url: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>;
"push": (path: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>;
/**
* The root path to use when matching URLs. By default, this is set to "/", but you can specify an alternate prefix for all URL paths.
*/

View File

@ -100,9 +100,9 @@ Type: `Promise<void>`
### `push(url: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>`
### `push(path: string, direction?: RouterDirection, animation?: AnimationBuilder | undefined) => Promise<boolean>`
Navigate to the specified URL.
Navigate to the specified path.
#### Returns

View File

@ -117,18 +117,21 @@ export class Router implements ComponentInterface {
}
/**
* Navigate to the specified URL.
* Navigate to the specified path.
*
* @param url The url to navigate to.
* @param path The path to navigate to.
* @param direction The direction of the animation. Defaults to `"forward"`.
*/
@Method()
async push(url: string, direction: RouterDirection = 'forward', animation?: AnimationBuilder) {
if (url.startsWith('.')) {
url = (new URL(url, window.location.href)).pathname;
async push(path: string, direction: RouterDirection = 'forward', animation?: AnimationBuilder) {
if (path.startsWith('.')) {
const currentPath = this.previousPath ?? '/';
// Convert currentPath to an URL by pre-pending a protocol and a host to resolve the relative path.
const url = new URL(path, `https://host/${currentPath}`);
path = url.pathname + url.search;
}
let parsedPath = parsePath(url);
let parsedPath = parsePath(path);
const canProceed = await this.runGuards(parsedPath.segments);
if (canProceed !== true) {

View File

@ -57,6 +57,8 @@
<p><a href='#/two/three/hello'>Go to page 3 (hello)</a></p>
<p><a href='#/two/second-page'>Go to page 2</a></p>
<p><a href='#/two/'>Go to page 1</a></p>
<ion-button id="btn-rel" href="./relative?param=1">Page 3 (relative)</ion-button>
<ion-button id="btn-abs" href="/two/three/absolute">Page 3 (absolute)</ion-button>
</ion-content>`;
}
}

View File

@ -0,0 +1,29 @@
import { newE2EPage } from '@stencil/core/testing';
test('push should support relative path', async () => {
const page = await newE2EPage({
url: '/src/components/router/test/basic#/two/three/hola?ionic:_testing=true'
});
await page.waitForChanges();
const backButton = await page.$('#btn-rel');
await backButton.click();
await page.waitForChanges();
const url = await page.url();
expect(url).toContain('#/two/three/relative?param=1');
});
test('push should support absolute path', async () => {
const page = await newE2EPage({
url: '/src/components/router/test/basic#/two/three/hola?ionic:_testing=true'
});
await page.waitForChanges();
const backButton = await page.$('#btn-abs');
await backButton.click();
await page.waitForChanges();
const url = await page.url();
expect(url).toContain('#/two/three/absolute');
});