fix(router): fixes navChanged()

This commit is contained in:
Manu Mtz.-Almeida
2018-03-26 22:07:00 +02:00
parent 076b7e55bd
commit dddaee1719
17 changed files with 120 additions and 111 deletions

View File

@@ -1,6 +1,6 @@
import { NavOutlet, NavOutletElement, RouteChain, RouteID } from './interfaces';
import { NavOutlet, NavOutletElement, RouteChain, RouteID, RouterDirection } from './interfaces';
export async function writeNavState(root: HTMLElement|undefined, chain: RouteChain|null, index: number, direction: number): Promise<boolean> {
export async function writeNavState(root: HTMLElement|undefined, chain: RouteChain|null, direction: RouterDirection, index: number): Promise<boolean> {
// find next navigation outlet in the DOM
const outlet = searchNavNode(root);
@@ -16,11 +16,11 @@ export async function writeNavState(root: HTMLElement|undefined, chain: RouteCha
// if the outlet changed the page, reset navigation to neutral (no direction)
// this means nested outlets will not animate
if (result.changed) {
direction = 0;
direction = RouterDirection.None;
}
// recursivelly set nested outlets
const changed = await writeNavState(result.element, chain, index + 1, direction);
const changed = await writeNavState(result.element, chain, direction, index + 1);
// once all nested outlets are visible let's make the parent visible too,
// using markVisible prevents flickering
@@ -30,14 +30,14 @@ export async function writeNavState(root: HTMLElement|undefined, chain: RouteCha
return changed;
}
export function readNavState(root: HTMLElement) {
export function readNavState(root: HTMLElement | null) {
const ids: RouteID[] = [];
let pivot: NavOutlet|null;
let node: HTMLElement|undefined = root;
let outlet: NavOutlet|null;
let node: HTMLElement|null = root;
while (true) {
pivot = searchNavNode(node);
if (pivot) {
const id = pivot.getRouteId();
outlet = searchNavNode(node);
if (outlet) {
const id = outlet.getRouteId();
if (id) {
node = id.element;
id.element = undefined;
@@ -49,7 +49,7 @@ export function readNavState(root: HTMLElement) {
break;
}
}
return {ids, pivot};
return {ids, outlet};
}
const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';

View File

@@ -10,6 +10,12 @@ export interface RouterEventDetail {
to: string;
}
export const enum RouterDirection {
None = 0,
Forward = 1,
Back = -1,
}
export interface RouteRedirect {
from: string[];
to: string[]|undefined;

View File

@@ -1,6 +1,5 @@
import { RouteChain, RouteNode, RouteRedirect, RouteTree } from './interfaces';
import { parsePath } from './path';
import { mergeParams } from './matching';
export function readRedirects(root: Element): RouteRedirect[] {
@@ -16,16 +15,13 @@ export function readRedirects(root: Element): RouteRedirect[] {
}
export function readRoutes(root: Element, node = root): RouteTree {
const commonParams = {
router: root
};
return (Array.from(node.children) as HTMLIonRouteElement[])
.filter(el => el.tagName === 'ION-ROUTE' && el.component)
.map(el => {
return {
path: parsePath(readProp(el, 'url')),
id: readProp(el, 'component').toLowerCase(),
params: mergeParams(commonParams, el.componentProps),
params: el.componentProps,
children: readRoutes(root, el)
};
});

View File

@@ -1,4 +1,4 @@
import { RouteChain } from './interfaces';
import { RouteChain, RouterDirection } from './interfaces';
export function generatePath(segments: string[]): string {
const path = segments
@@ -8,14 +8,14 @@ export function generatePath(segments: string[]): string {
return '/' + path;
}
export function chainToPath(chain: RouteChain): string[] {
export function chainToPath(chain: RouteChain): string[]|null {
const path = [];
for (const route of chain) {
for (const segment of route.path) {
if (segment[0] === ':') {
const param = route.params && route.params[segment.slice(1)];
if (!param) {
throw new Error(`missing param ${segment.slice(1)}`);
return null;
}
path.push(param);
} else if (segment !== '') {
@@ -26,17 +26,16 @@ export function chainToPath(chain: RouteChain): string[] {
return path;
}
export function writePath(history: History, base: string, usePath: boolean, path: string[], isPop: boolean, state: number) {
export function writePath(history: History, base: string, usePath: boolean, path: string[], direction: RouterDirection, state: number) {
path = [base, ...path];
let url = generatePath(path);
if (usePath) {
url = '#' + url;
}
if (isPop) {
// history.back();
history.replaceState(state, '', url);
} else {
if (direction === RouterDirection.Forward) {
history.pushState(state, '', url);
} else {
history.replaceState(state, '', url);
}
}