diff --git a/core/src/components/anchor/anchor.tsx b/core/src/components/anchor/anchor.tsx index 9a38eda968..c81fa08d33 100644 --- a/core/src/components/anchor/anchor.tsx +++ b/core/src/components/anchor/anchor.tsx @@ -1,5 +1,5 @@ import { Component, Prop } from '@stencil/core'; -import { openURL } from '../../utils/theme'; +import { RouterDirection, openURL } from '../../utils/theme'; @Component({ @@ -19,7 +19,7 @@ export class Anchor { * When using a router, it specifies the transition direction when navigating to * another page using `href`. */ - @Prop() routerDirection?: 'forward' | 'back'; + @Prop() routerDirection?: RouterDirection; render() { return matches(v, id, params)); - let resolve: (result: RouteWrite) => void; const promise = new Promise((r) => resolve = r); let finish: Promise; @@ -202,14 +200,19 @@ export class Nav implements NavOutlet { return p; } }; - if (viewController) { - finish = this.popTo(viewController, {...commonOpts, direction: 'back'}); - } else if (direction === 1) { - finish = this.push(id, params, commonOpts); - } else if (direction === -1) { - finish = this.setRoot(id, params, {...commonOpts, direction: 'back', animated: true}); - } else { + + if (direction === 0) { finish = this.setRoot(id, params, commonOpts); + } else { + const viewController = this.views.find(v => matches(v, id, params)); + + if (viewController) { + finish = this.popTo(viewController, {...commonOpts, direction: 'back'}); + } else if (direction === 1) { + finish = this.push(id, params, commonOpts); + } else if (direction === -1) { + finish = this.setRoot(id, params, {...commonOpts, direction: 'back', animated: true}); + } } return promise; } diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index 0211798445..57360b44d1 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -72,34 +72,13 @@ export class Router { return this.writeNavStateRoot(path, direction); } - private onRedirectChanged() { - const path = this.getPath(); - if (path && routeRedirect(path, readRedirects(this.el))) { - this.writeNavStateRoot(path, RouterDirection.None); - } - } + @Method() + push(url: string, direction = RouterDirection.Forward) { + const path = parsePath(url); + console.debug('[ion-router] URL pushed -> updating nav', url, direction); - private onRoutesChanged() { - return this.writeNavStateRoot(this.getPath(), RouterDirection.None); - } - - private historyDirection() { - if (this.win.history.state === null) { - this.state++; - this.win.history.replaceState(this.state, this.win.document.title, this.win.document.location.href); - } - - const state = this.win.history.state; - const lastState = this.lastState; - this.lastState = state; - - if (state > lastState) { - return RouterDirection.Forward; - } else if (state < lastState) { - return RouterDirection.Back; - } else { - return RouterDirection.None; - } + this.setPath(path, direction); + return this.writeNavStateRoot(path, direction); } @Method() @@ -136,15 +115,37 @@ export class Router { return true; } - @Method() - push(url: string, direction = RouterDirection.Forward) { - const path = parsePath(url); - console.debug('[ion-router] URL pushed -> updating nav', url, direction); - - this.setPath(path, direction); - return this.writeNavStateRoot(path, direction); + private onRedirectChanged() { + const path = this.getPath(); + if (path && routeRedirect(path, readRedirects(this.el))) { + this.writeNavStateRoot(path, RouterDirection.None); + } } + private onRoutesChanged() { + return this.writeNavStateRoot(this.getPath(), RouterDirection.None); + } + + private historyDirection() { + if (this.win.history.state === null) { + this.state++; + this.win.history.replaceState(this.state, this.win.document.title, this.win.document.location.href); + } + + const state = this.win.history.state; + const lastState = this.lastState; + this.lastState = state; + + if (state > lastState) { + return RouterDirection.Forward; + } else if (state < lastState) { + return RouterDirection.Back; + } else { + return RouterDirection.None; + } + } + + private async writeNavStateRoot(path: string[]|null, direction: RouterDirection): Promise { if (this.busy) { return false; diff --git a/core/src/utils/theme.ts b/core/src/utils/theme.ts index 6cbb3d1c65..ed2e9ce8e3 100644 --- a/core/src/utils/theme.ts +++ b/core/src/utils/theme.ts @@ -64,7 +64,7 @@ export function getClassMap(classes: string | string[] | undefined): CssClassMap return map; } -export type RouterDirection = 'forward' | 'back'; +export type RouterDirection = 'forward' | 'back' | 'root'; export async function openURL(win: Window, url: string|undefined, ev: Event, direction: RouterDirection = 'forward') { if (url && url[0] !== '#' && url.indexOf('://') === -1) { @@ -72,8 +72,14 @@ export async function openURL(win: Window, url: string|undefined, ev: Event, dir if (router) { ev && ev.preventDefault(); await router.componentOnReady(); - return router.push(url, direction === 'back' ? -1 : 1); + return router.push(url, DIRECTION_MAP[direction]); } } return Promise.resolve(); } + +const DIRECTION_MAP = { + 'back': -1, + 'root': 0, + 'forward': 1 +};