fix(router): accepts root direction

This commit is contained in:
Manu Mtz.-Almeida
2018-05-11 18:56:29 +02:00
parent 0b27696d30
commit ae9d0c7236
6 changed files with 61 additions and 51 deletions

View File

@ -1,5 +1,5 @@
import { Component, Prop } from '@stencil/core'; import { Component, Prop } from '@stencil/core';
import { openURL } from '../../utils/theme'; import { RouterDirection, openURL } from '../../utils/theme';
@Component({ @Component({
@ -19,7 +19,7 @@ export class Anchor {
* When using a router, it specifies the transition direction when navigating to * When using a router, it specifies the transition direction when navigating to
* another page using `href`. * another page using `href`.
*/ */
@Prop() routerDirection?: 'forward' | 'back'; @Prop() routerDirection?: RouterDirection;
render() { render() {
return <a return <a

View File

@ -1,6 +1,6 @@
import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core'; import { Component, Element, Event, EventEmitter, Prop, State } from '@stencil/core';
import { CssClassMap, Mode } from '../../interface'; import { CssClassMap, Mode } from '../../interface';
import { getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme'; import { RouterDirection, getButtonClassMap, getElementClassMap, openURL } from '../../utils/theme';
@Component({ @Component({
@ -59,7 +59,7 @@ export class Button {
* When using a router, it specifies the transition direction when navigating to * When using a router, it specifies the transition direction when navigating to
* another page using `href`. * another page using `href`.
*/ */
@Prop() routerDirection?: 'forward' | 'back'; @Prop() routerDirection?: RouterDirection;
/** /**
* Contains a URL or a URL fragment that the hyperlink points to. * Contains a URL or a URL fragment that the hyperlink points to.

View File

@ -1,6 +1,6 @@
import { Component, Element, Listen, Prop } from '@stencil/core'; import { Component, Element, Listen, Prop } from '@stencil/core';
import { CssClassMap, Mode } from '../../interface'; import { CssClassMap, Mode } from '../../interface';
import { createThemedClasses, getElementClassMap, openURL } from '../../utils/theme'; import { RouterDirection, createThemedClasses, getElementClassMap, openURL } from '../../utils/theme';
@Component({ @Component({
@ -63,7 +63,7 @@ export class Item {
* When using a router, it specifies the transition direction when navigating to * When using a router, it specifies the transition direction when navigating to
* another page using `href`. * another page using `href`.
*/ */
@Prop() routerDirection?: 'forward' | 'back'; @Prop() routerDirection?: RouterDirection;
@Listen('ionStyle') @Listen('ionStyle')

View File

@ -181,8 +181,6 @@ export class Nav implements NavOutlet {
}); });
} }
const viewController = this.views.find(v => matches(v, id, params));
let resolve: (result: RouteWrite) => void; let resolve: (result: RouteWrite) => void;
const promise = new Promise<RouteWrite>((r) => resolve = r); const promise = new Promise<RouteWrite>((r) => resolve = r);
let finish: Promise<boolean>; let finish: Promise<boolean>;
@ -202,14 +200,19 @@ export class Nav implements NavOutlet {
return p; return p;
} }
}; };
if (direction === 0) {
finish = this.setRoot(id, params, commonOpts);
} else {
const viewController = this.views.find(v => matches(v, id, params));
if (viewController) { if (viewController) {
finish = this.popTo(viewController, {...commonOpts, direction: 'back'}); finish = this.popTo(viewController, {...commonOpts, direction: 'back'});
} else if (direction === 1) { } else if (direction === 1) {
finish = this.push(id, params, commonOpts); finish = this.push(id, params, commonOpts);
} else if (direction === -1) { } else if (direction === -1) {
finish = this.setRoot(id, params, {...commonOpts, direction: 'back', animated: true}); finish = this.setRoot(id, params, {...commonOpts, direction: 'back', animated: true});
} else { }
finish = this.setRoot(id, params, commonOpts);
} }
return promise; return promise;
} }

View File

@ -72,34 +72,13 @@ export class Router {
return this.writeNavStateRoot(path, direction); return this.writeNavStateRoot(path, direction);
} }
private onRedirectChanged() { @Method()
const path = this.getPath(); push(url: string, direction = RouterDirection.Forward) {
if (path && routeRedirect(path, readRedirects(this.el))) { const path = parsePath(url);
this.writeNavStateRoot(path, RouterDirection.None); console.debug('[ion-router] URL pushed -> updating nav', url, direction);
}
}
private onRoutesChanged() { this.setPath(path, direction);
return this.writeNavStateRoot(this.getPath(), RouterDirection.None); return this.writeNavStateRoot(path, direction);
}
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;
}
} }
@Method() @Method()
@ -136,14 +115,36 @@ export class Router {
return true; return true;
} }
@Method() private onRedirectChanged() {
push(url: string, direction = RouterDirection.Forward) { const path = this.getPath();
const path = parsePath(url); if (path && routeRedirect(path, readRedirects(this.el))) {
console.debug('[ion-router] URL pushed -> updating nav', url, direction); this.writeNavStateRoot(path, RouterDirection.None);
this.setPath(path, direction);
return this.writeNavStateRoot(path, 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;
}
}
private async writeNavStateRoot(path: string[]|null, direction: RouterDirection): Promise<boolean> { private async writeNavStateRoot(path: string[]|null, direction: RouterDirection): Promise<boolean> {
if (this.busy) { if (this.busy) {

View File

@ -64,7 +64,7 @@ export function getClassMap(classes: string | string[] | undefined): CssClassMap
return map; 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') { export async function openURL(win: Window, url: string|undefined, ev: Event, direction: RouterDirection = 'forward') {
if (url && url[0] !== '#' && url.indexOf('://') === -1) { 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) { if (router) {
ev && ev.preventDefault(); ev && ev.preventDefault();
await router.componentOnReady(); await router.componentOnReady();
return router.push(url, direction === 'back' ? -1 : 1); return router.push(url, DIRECTION_MAP[direction]);
} }
} }
return Promise.resolve(); return Promise.resolve();
} }
const DIRECTION_MAP = {
'back': -1,
'root': 0,
'forward': 1
};