diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 59ef8a3dde..d15e86fcad 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -56,6 +56,9 @@ import { PopoverOptions, RangeInputChangeEvent, RouteID, + RouterDirection, + RouterEventDetail, + RouterIntent, RouterOutletOptions, RouteWrite, SelectInputChangeEvent, @@ -82,10 +85,6 @@ import { import { ViewController, } from './components/nav/view-controller'; -import { - RouterDirection, - RouterEventDetail, -} from './components/router/utils/interface'; import { ScrollBaseDetail, ScrollDetail, @@ -492,7 +491,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection': 'forward' | 'back'; + 'routerDirection': RouterDirection; } } @@ -522,7 +521,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection'?: 'forward' | 'back'; + 'routerDirection'?: RouterDirection; } } } @@ -839,7 +838,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection': 'forward' | 'back'; + 'routerDirection': RouterDirection; /** * The button shape. Possible values are: `"round"`. */ @@ -917,7 +916,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection'?: 'forward' | 'back'; + 'routerDirection'?: RouterDirection; /** * The button shape. Possible values are: `"round"`. */ @@ -2863,7 +2862,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection': 'forward' | 'back'; + 'routerDirection': RouterDirection; } } @@ -2917,7 +2916,7 @@ declare global { /** * When using a router, it specifies the transition direction when navigating to another page using `href`. */ - 'routerDirection'?: 'forward' | 'back'; + 'routerDirection'?: RouterDirection; } } } @@ -3862,7 +3861,7 @@ declare global { 'rootParams': ComponentProps; 'setPages': (views: any[], opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise; 'setRoot': (component: NavComponent, componentProps?: ComponentProps | null | undefined, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise; - 'setRouteId': (id: string, params: any, direction: number) => Promise; + 'setRouteId': (id: string, params: any, direction: RouterIntent) => Promise; 'swipeBackEnabled': boolean; } } @@ -5153,7 +5152,7 @@ declare global { namespace StencilComponents { interface IonRouter { - 'navChanged': (direction: RouterDirection) => Promise; + 'navChanged': (intent: RouterIntent) => Promise; 'printDebug': () => void; 'push': (url: string, direction?: RouterDirection) => Promise; /** diff --git a/core/src/components/anchor/anchor.tsx b/core/src/components/anchor/anchor.tsx index c81fa08d33..47e1aa0bd6 100644 --- a/core/src/components/anchor/anchor.tsx +++ b/core/src/components/anchor/anchor.tsx @@ -1,5 +1,6 @@ import { Component, Prop } from '@stencil/core'; -import { RouterDirection, openURL } from '../../utils/theme'; +import { RouterDirection } from '../../interface'; +import { openURL } from '../../utils/theme'; @Component({ diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index 1ac820bad3..bdf925631f 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -1,6 +1,6 @@ import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core'; -import { CssClassMap, Mode } from '../../interface'; -import { RouterDirection, getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme'; +import { CssClassMap, Mode, RouterDirection } from '../../interface'; +import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme'; @Component({ diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx index c49ec17860..7404836cbd 100644 --- a/core/src/components/item/item.tsx +++ b/core/src/components/item/item.tsx @@ -1,6 +1,6 @@ import { Component, Element, Listen, Prop } from '@stencil/core'; -import { CssClassMap, Mode } from '../../interface'; -import { RouterDirection, createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; +import { CssClassMap, Mode, RouterDirection } from '../../interface'; +import { createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; @Component({ diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index b4d8029106..a852e7390f 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -3,7 +3,7 @@ import { ViewLifecycle } from '../..'; import { Animation, ComponentProps, Config, FrameworkDelegate, GestureDetail, Mode, NavComponent, NavOptions, NavOutlet, NavResult, QueueController, RouteID, - RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction } from '../../interface'; + RouteWrite, RouterIntent, TransitionDoneFn, TransitionInstruction } from '../../interface'; import { assert } from '../../utils/helpers'; import { TransitionOptions, lifecycle, transition } from '../../utils/transition'; import { ViewController, ViewState, convertToViews, matches } from './view-controller'; @@ -172,7 +172,7 @@ export class Nav implements NavOutlet { } @Method() - setRouteId(id: string, params: any, direction: number): Promise { + setRouteId(id: string, params: any, direction: RouterIntent): Promise { const active = this.getActive(); if (matches(active, id, params)) { return Promise.resolve({ @@ -310,8 +310,8 @@ export class Nav implements NavOutlet { const router = this.win.document.querySelector('ion-router'); if (router) { const direction = (result.direction === 'back') - ? RouterDirection.Back - : RouterDirection.Forward; + ? RouterIntent.Back + : RouterIntent.Forward; router.navChanged(direction); } diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index 57360b44d1..2c7a53e860 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -1,9 +1,8 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { Config, QueueController } from '../../interface'; +import { Config, QueueController, RouteChain, RouterDirection, RouterEventDetail, RouterIntent } from '../../interface'; import { debounce } from '../../utils/helpers'; import { printRedirects, printRoutes } from './utils/debug'; import { readNavState, waitUntilNavNode, writeNavState } from './utils/dom'; -import { RouteChain, RouterDirection, RouterEventDetail } from './utils/interface'; import { routeRedirect, routerIDsToChain, routerPathToChain } from './utils/matching'; import { readRedirects, readRoutes } from './utils/parser'; import { chainToPath, generatePath, parsePath, readPath, writePath } from './utils/path'; @@ -73,12 +72,13 @@ export class Router { } @Method() - push(url: string, direction = RouterDirection.Forward) { + push(url: string, direction: RouterDirection = 'forward') { const path = parsePath(url); + const intent = DIRECTION_TO_INTENT[direction]; console.debug('[ion-router] URL pushed -> updating nav', url, direction); - this.setPath(path, direction); - return this.writeNavStateRoot(path, direction); + this.setPath(path, intent); + return this.writeNavStateRoot(path, intent); } @Method() @@ -90,7 +90,7 @@ export class Router { } @Method() - async navChanged(direction: RouterDirection): Promise { + async navChanged(intent: RouterIntent): Promise { if (this.busy) { return false; } @@ -109,21 +109,21 @@ export class Router { } console.debug('[ion-router] nav changed -> update URL', ids, path); - this.setPath(path, direction); + this.setPath(path, intent); - await this.writeNavState(outlet, chain, RouterDirection.None, path, null, ids.length); + await this.writeNavState(outlet, chain, RouterIntent.None, path, null, ids.length); return true; } private onRedirectChanged() { const path = this.getPath(); if (path && routeRedirect(path, readRedirects(this.el))) { - this.writeNavStateRoot(path, RouterDirection.None); + this.writeNavStateRoot(path, RouterIntent.None); } } private onRoutesChanged() { - return this.writeNavStateRoot(this.getPath(), RouterDirection.None); + return this.writeNavStateRoot(this.getPath(), RouterIntent.None); } private historyDirection() { @@ -137,16 +137,16 @@ export class Router { this.lastState = state; if (state > lastState) { - return RouterDirection.Forward; + return RouterIntent.Forward; } else if (state < lastState) { - return RouterDirection.Back; + return RouterIntent.Back; } else { - return RouterDirection.None; + return RouterIntent.None; } } - private async writeNavStateRoot(path: string[]|null, direction: RouterDirection): Promise { + private async writeNavStateRoot(path: string[]|null, intent: RouterIntent): Promise { if (this.busy) { return false; } @@ -160,7 +160,7 @@ export class Router { const redirect = routeRedirect(path, redirects); let redirectFrom: string[]|null = null; if (redirect) { - this.setPath(redirect.to, direction); + this.setPath(redirect.to, intent); redirectFrom = redirect.from; path = redirect.to; } @@ -174,11 +174,11 @@ export class Router { } // write DOM give - return this.writeNavState(this.win.document.body, chain, direction, path, redirectFrom); + return this.writeNavState(this.win.document.body, chain, intent, path, redirectFrom); } private async writeNavState( - node: HTMLElement|undefined, chain: RouteChain, direction: RouterDirection, + node: HTMLElement|undefined, chain: RouteChain, intent: RouterIntent, path: string[], redirectFrom: string[] | null, index = 0 ): Promise { @@ -191,7 +191,7 @@ export class Router { const routeEvent = this.routeChangeEvent(path, redirectFrom); routeEvent && this.ionRouteWillChange.emit(routeEvent); - const changed = await writeNavState(node, chain, direction, index); + const changed = await writeNavState(node, chain, intent, index); this.busy = false; if (changed) { @@ -204,9 +204,9 @@ export class Router { return changed; } - private setPath(path: string[], direction: RouterDirection) { + private setPath(path: string[], intent: RouterIntent) { this.state++; - writePath(this.win.history, this.root, this.useHash, path, direction, this.state); + writePath(this.win.history, this.root, this.useHash, path, intent, this.state); } private getPath(): string[] | null { @@ -228,3 +228,9 @@ export class Router { }; } } + +const DIRECTION_TO_INTENT = { + 'back': RouterIntent.Back, + 'root': RouterIntent.None, + 'forward': RouterIntent.Forward +}; diff --git a/core/src/components/router/utils/dom.ts b/core/src/components/router/utils/dom.ts index 925d65c6cf..6f49ecc638 100644 --- a/core/src/components/router/utils/dom.ts +++ b/core/src/components/router/utils/dom.ts @@ -1,6 +1,6 @@ -import { NavOutletElement, RouteChain, RouteID, RouterDirection } from './interface'; +import { NavOutletElement, RouteChain, RouteID, RouterIntent } from '../../../interface'; -export async function writeNavState(root: HTMLElement | undefined, chain: RouteChain, direction: RouterDirection, index: number, changed = false): Promise { +export async function writeNavState(root: HTMLElement | undefined, chain: RouteChain, intent: RouterIntent, index: number, changed = false): Promise { try { // find next navigation outlet in the DOM const outlet = searchNavNode(root); @@ -12,17 +12,17 @@ export async function writeNavState(root: HTMLElement | undefined, chain: RouteC await outlet.componentOnReady(); const route = chain[index]; - const result = await outlet.setRouteId(route.id, route.params, direction); + const result = await outlet.setRouteId(route.id, route.params, intent); // if the outlet changed the page, reset navigation to neutral (no direction) // this means nested outlets will not animate if (result.changed) { - direction = RouterDirection.None; + intent = RouterIntent.None; changed = true; } // recursivelly set nested outlets - changed = await writeNavState(result.element, chain, direction, index + 1, changed); + changed = await writeNavState(result.element, chain, intent, index + 1, changed); // once all nested outlets are visible let's make the parent visible too, // using markVisible prevents flickering diff --git a/core/src/components/router/utils/interface.ts b/core/src/components/router/utils/interface.ts index 5e89504521..aebeb2f2cf 100644 --- a/core/src/components/router/utils/interface.ts +++ b/core/src/components/router/utils/interface.ts @@ -1,6 +1,6 @@ export interface NavOutlet { - setRouteId(id: string, data: any, direction: number): Promise; + setRouteId(id: string, data: any, direction: RouterIntent): Promise; getRouteId(): RouteID|undefined; } @@ -10,7 +10,9 @@ export interface RouterEventDetail { to: string; } -export const enum RouterDirection { +export type RouterDirection = 'forward' | 'back' | 'root'; + +export const enum RouterIntent { None = 0, Forward = 1, Back = -1, diff --git a/core/src/components/router/utils/path.ts b/core/src/components/router/utils/path.ts index eb2339fd76..4c7e8b58c9 100644 --- a/core/src/components/router/utils/path.ts +++ b/core/src/components/router/utils/path.ts @@ -1,4 +1,4 @@ -import { RouteChain, RouterDirection } from './interface'; +import { RouteChain, RouterIntent } from '../../../interface'; export function generatePath(segments: string[]): string { const path = segments @@ -26,7 +26,7 @@ export function chainToPath(chain: RouteChain): string[]|null { return path; } -export function writePath(history: History, root: string, useHash: boolean, path: string[], direction: RouterDirection, state: number) { +export function writePath(history: History, root: string, useHash: boolean, path: string[], intent: RouterIntent, state: number) { let url = generatePath([ ...parsePath(root), ...path @@ -34,7 +34,7 @@ export function writePath(history: History, root: string, useHash: boolean, path if (useHash) { url = '#' + url; } - if (direction === RouterDirection.Forward) { + if (intent === RouterIntent.Forward) { history.pushState(state, '', url); } else { history.replaceState(state, '', url); diff --git a/core/src/components/tabs/tabs.tsx b/core/src/components/tabs/tabs.tsx index 026ee1390b..914539418f 100644 --- a/core/src/components/tabs/tabs.tsx +++ b/core/src/components/tabs/tabs.tsx @@ -1,5 +1,5 @@ import { Build, Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core'; -import { Config, NavOutlet, RouteID, RouteWrite, RouterDirection } from '../../interface'; +import { Config, NavOutlet, RouteID, RouteWrite, RouterIntent } from '../../interface'; import { TabbarLayout, TabbarPlacement } from '../tabbar/tabbar'; @@ -262,7 +262,7 @@ export class Tabs implements NavOutlet { if (this.useRouter) { const router = this.doc.querySelector('ion-router'); if (router) { - return router.navChanged(RouterDirection.Forward); + return router.navChanged(RouterIntent.Forward); } } return Promise.resolve(false); diff --git a/core/src/utils/theme.ts b/core/src/utils/theme.ts index ed2e9ce8e3..8572bbf4b5 100644 --- a/core/src/utils/theme.ts +++ b/core/src/utils/theme.ts @@ -1,4 +1,4 @@ -import { CssClassMap, Mode } from '../interface'; +import { CssClassMap, Mode, RouterDirection } from '../interface'; /** * Create the mode and color classes for the component based on the classes passed in @@ -64,22 +64,14 @@ export function getClassMap(classes: string | string[] | undefined): CssClassMap return map; } -export type RouterDirection = 'forward' | 'back' | 'root'; - -export async function openURL(win: Window, url: string|undefined, ev: Event, direction: RouterDirection = 'forward') { +export async function openURL(win: Window, url: string|undefined, ev: Event, direction?: RouterDirection) { if (url && url[0] !== '#' && url.indexOf('://') === -1) { const router = win.document.querySelector('ion-router'); if (router) { ev && ev.preventDefault(); await router.componentOnReady(); - return router.push(url, DIRECTION_MAP[direction]); + return router.push(url, direction); } } return Promise.resolve(); } - -const DIRECTION_MAP = { - 'back': -1, - 'root': 0, - 'forward': 1 -};