mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 13:01:01 +08:00
feat(router): adds parameters
This commit is contained in:
2
packages/core/src/components.d.ts
vendored
2
packages/core/src/components.d.ts
vendored
@ -2600,8 +2600,8 @@ declare global {
|
|||||||
namespace JSXElements {
|
namespace JSXElements {
|
||||||
export interface IonRouteAttributes extends HTMLAttributes {
|
export interface IonRouteAttributes extends HTMLAttributes {
|
||||||
component?: string;
|
component?: string;
|
||||||
|
params?: undefined;
|
||||||
path?: string;
|
path?: string;
|
||||||
props?: any;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,11 +223,6 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
|
||||||
markVisible() {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
getContentElement(): HTMLElement {
|
getContentElement(): HTMLElement {
|
||||||
const active = this.getActive();
|
const active = this.getActive();
|
||||||
|
@ -71,9 +71,6 @@ Return a view controller
|
|||||||
#### insertPages()
|
#### insertPages()
|
||||||
|
|
||||||
|
|
||||||
#### markVisible()
|
|
||||||
|
|
||||||
|
|
||||||
#### pop()
|
#### pop()
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,16 +12,16 @@
|
|||||||
string
|
string
|
||||||
|
|
||||||
|
|
||||||
|
#### params
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### path
|
#### path
|
||||||
|
|
||||||
string
|
string
|
||||||
|
|
||||||
|
|
||||||
#### props
|
|
||||||
|
|
||||||
any
|
|
||||||
|
|
||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
#### component
|
#### component
|
||||||
@ -29,16 +29,16 @@ any
|
|||||||
string
|
string
|
||||||
|
|
||||||
|
|
||||||
|
#### params
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### path
|
#### path
|
||||||
|
|
||||||
string
|
string
|
||||||
|
|
||||||
|
|
||||||
#### props
|
|
||||||
|
|
||||||
any
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
|
@ -7,5 +7,5 @@ import { Component, Prop } from '@stencil/core';
|
|||||||
export class Route {
|
export class Route {
|
||||||
@Prop() path = '';
|
@Prop() path = '';
|
||||||
@Prop() component: string;
|
@Prop() component: string;
|
||||||
@Prop() props: any = {};
|
@Prop() params: undefined;
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
import { RouteChain } from '../utils/interfaces';
|
import { RouteChain } from '../utils/interfaces';
|
||||||
import { matchesIDs, matchesPath, routerPathToChain } from '../utils/matching';
|
import { matchesIDs, matchesPath, mergeParams, routerPathToChain } from '../utils/matching';
|
||||||
import { mockRouteElement } from './parser.spec';
|
import { parsePath } from '../utils/path';
|
||||||
import { mockElement } from '@stencil/core/dist/testing';
|
|
||||||
|
|
||||||
const CHAIN_1: RouteChain = [
|
const CHAIN_1: RouteChain = [
|
||||||
{ id: '2', path: ['to'], props: undefined },
|
{ id: '2', path: ['to'], params: undefined },
|
||||||
{ id: '1', path: ['path'], props: undefined },
|
{ id: '1', path: ['path'], params: undefined },
|
||||||
{ id: '3', path: ['segment'], props: undefined },
|
{ id: '3', path: ['segment'], params: undefined },
|
||||||
{ id: '4', path: [''], props: undefined },
|
{ id: '4', path: [''], params: undefined },
|
||||||
];
|
];
|
||||||
|
|
||||||
const CHAIN_2: RouteChain = [
|
const CHAIN_2: RouteChain = [
|
||||||
{ id: '2', path: [''], props: undefined },
|
{ id: '2', path: [''], params: undefined },
|
||||||
{ id: '1', path: [''], props: undefined },
|
{ id: '1', path: [''], params: undefined },
|
||||||
{ id: '3', path: ['segment', 'to'], props: undefined },
|
{ id: '3', path: ['segment', 'to'], params: undefined },
|
||||||
{ id: '4', path: [''], props: undefined },
|
{ id: '4', path: [''], params: undefined },
|
||||||
{ id: '5', path: ['hola'], props: undefined },
|
{ id: '5', path: ['hola'], params: undefined },
|
||||||
{ id: '6', path: [''], props: undefined },
|
{ id: '6', path: [''], params: undefined },
|
||||||
{ id: '7', path: [''], props: undefined },
|
{ id: '7', path: [''], params: undefined },
|
||||||
{ id: '8', path: ['adios', 'que', 'tal'], props: undefined },
|
{ id: '8', path: ['adios', 'que', 'tal'], params: undefined },
|
||||||
];
|
];
|
||||||
|
|
||||||
const CHAIN_3: RouteChain = [
|
const CHAIN_3: RouteChain = [
|
||||||
{ id: '2', path: ['this', 'to'], props: undefined },
|
{ id: '2', path: ['this', 'to'], params: undefined },
|
||||||
{ id: '1', path: ['path'], props: undefined },
|
{ id: '1', path: ['path'], params: undefined },
|
||||||
{ id: '3', path: ['segment', 'to', 'element'], props: undefined },
|
{ id: '3', path: ['segment', 'to', 'element'], params: undefined },
|
||||||
{ id: '4', path: [''], props: undefined },
|
{ id: '4', path: [''], params: undefined },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@ -47,67 +46,85 @@ describe('matchesIDs', () => {
|
|||||||
describe('matchesPath', () => {
|
describe('matchesPath', () => {
|
||||||
it('should match simple path', () => {
|
it('should match simple path', () => {
|
||||||
const chain: RouteChain = CHAIN_3;
|
const chain: RouteChain = CHAIN_3;
|
||||||
expect(matchesPath(['this'], chain)).toBe(false);
|
expect(matchesPath(['this'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['this', 'to'], chain)).toBe(false);
|
expect(matchesPath(['this', 'to'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['this', 'to', 'path'], chain)).toBe(false);
|
expect(matchesPath(['this', 'to', 'path'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['this', 'to', 'path', 'segment'], chain)).toBe(false);
|
expect(matchesPath(['this', 'to', 'path', 'segment'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['this', 'to', 'path', 'segment', 'to'], chain)).toBe(false);
|
expect(matchesPath(['this', 'to', 'path', 'segment', 'to'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element'], chain)).toBe(true);
|
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element'], chain)).toEqual(chain);
|
||||||
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element', 'more'], chain)).toBe(false);
|
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element', 'more'], chain)).toEqual(null);
|
||||||
|
|
||||||
expect(matchesPath([], chain)).toBe(false);
|
expect(matchesPath([], chain)).toEqual(null);
|
||||||
expect(matchesPath([''], chain)).toBe(false);
|
expect(matchesPath([''], chain)).toEqual(null);
|
||||||
expect(matchesPath(['path'], chain)).toBe(false);
|
expect(matchesPath(['path'], chain)).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match simple default route', () => {
|
it('should match simple default route', () => {
|
||||||
const chain: RouteChain = CHAIN_2;
|
const chain: RouteChain = CHAIN_2;
|
||||||
expect(matchesPath([''], chain)).toBe(false);
|
expect(matchesPath([''], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment'], chain)).toBe(false);
|
expect(matchesPath(['segment'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment', 'to'], chain)).toBe(false);
|
expect(matchesPath(['segment', 'to'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment', 'to', 'hola'], chain)).toBe(false);
|
expect(matchesPath(['segment', 'to', 'hola'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment', 'to', 'hola', 'adios'], chain)).toBe(false);
|
expect(matchesPath(['segment', 'to', 'hola', 'adios'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que'], chain)).toBe(false);
|
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que', 'tal'], chain)).toBe(true);
|
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que', 'tal'], chain)).toEqual(chain);
|
||||||
|
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que', 'tal', 'more'], chain)).toEqual(chain);
|
||||||
|
|
||||||
expect(matchesPath(['to'], chain)).toBe(false);
|
expect(matchesPath(['to'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['path', 'to'], chain)).toBe(false);
|
expect(matchesPath(['path', 'to'], chain)).toEqual(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match simple route 2', () => {
|
it('should match simple route 2', () => {
|
||||||
const chain: RouteChain = [{ id: '5', path: ['hola'], props: undefined }];
|
const chain: RouteChain = [{ id: '5', path: ['hola'], params: undefined }];
|
||||||
expect(matchesPath([''], chain)).toBe(false);
|
expect(matchesPath([''], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola'], chain)).toBe(true);
|
expect(matchesPath(['hola'], chain)).toEqual(chain);
|
||||||
expect(matchesPath(['hola', 'hola'], chain)).toBe(true);
|
expect(matchesPath(['hola', 'hola'], chain)).toEqual(chain);
|
||||||
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
|
expect(matchesPath(['hola', 'adios'], chain)).toEqual(chain);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match simple route 3', () => {
|
it('should match simple route 3', () => {
|
||||||
const chain: RouteChain = [{ id: '5', path: ['hola', 'adios'], props: undefined }];
|
const chain: RouteChain = [{ id: '5', path: ['hola', 'adios'], params: undefined }];
|
||||||
expect(matchesPath([''], chain)).toBe(false);
|
expect(matchesPath([''], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola'], chain)).toBe(false);
|
expect(matchesPath(['hola'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola', 'hola'], chain)).toBe(false);
|
expect(matchesPath(['hola', 'hola'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
|
expect(matchesPath(['hola', 'adios'], chain)).toEqual(chain);
|
||||||
|
expect(matchesPath(['hola', 'adios', 'bye'], chain)).toEqual(chain);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match simple route 4', () => {
|
it('should match simple route 4', () => {
|
||||||
const chain: RouteChain = [
|
const chain: RouteChain = [
|
||||||
{ id: '5', path: ['hola'], props: undefined },
|
{ id: '5', path: ['hola'], params: undefined },
|
||||||
{ id: '5', path: ['adios'], props: undefined }];
|
{ id: '5', path: ['adios'], params: undefined }];
|
||||||
|
|
||||||
expect(matchesPath([''], chain)).toBe(false);
|
expect(matchesPath([''], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola'], chain)).toBe(false);
|
expect(matchesPath(['hola'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola', 'hola'], chain)).toBe(false);
|
expect(matchesPath(['hola', 'hola'], chain)).toEqual(null);
|
||||||
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
|
expect(matchesPath(['hola', 'adios'], chain)).toEqual(chain);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match with parameters', () => {
|
||||||
|
const chain: RouteChain = [
|
||||||
|
{ id: '5', path: ['profile', ':name'], params: undefined },
|
||||||
|
{ id: '5', path: [''], params: undefined },
|
||||||
|
{ id: '5', path: ['image'], params: {size: 'lg'} },
|
||||||
|
{ id: '5', path: ['image', ':size', ':type'], params: {size: 'mg'} },
|
||||||
|
];
|
||||||
|
const matched = matchesPath(parsePath('/profile/manu/image/image/large/retina'), chain);
|
||||||
|
expect(matched).toEqual([
|
||||||
|
{ id: '5', path: ['profile', ':name'], params: {name: 'manu'} },
|
||||||
|
{ id: '5', path: [''], params: undefined },
|
||||||
|
{ id: '5', path: ['image'], params: {size: 'lg'} },
|
||||||
|
{ id: '5', path: ['image', ':size', ':type'], params: {size: 'large', type: 'retina'} },
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('routerPathToChain', () => {
|
describe('routerPathToChain', () => {
|
||||||
it('should match the route with higher priority', () => {
|
it('should match the route with higher priority', () => {
|
||||||
const chain3: RouteChain = [{ id: '5', path: ['hola'], props: undefined }];
|
const chain3: RouteChain = [{ id: '5', path: ['hola'], params: undefined }];
|
||||||
const chain4: RouteChain = [
|
const chain4: RouteChain = [
|
||||||
{ id: '5', path: ['hola'], props: undefined },
|
{ id: '5', path: ['hola'], params: undefined },
|
||||||
{ id: '5', path: ['adios'], props: undefined }];
|
{ id: '5', path: ['adios'], params: undefined }];
|
||||||
|
|
||||||
const routes: RouteChain[] = [
|
const routes: RouteChain[] = [
|
||||||
CHAIN_1,
|
CHAIN_1,
|
||||||
@ -147,14 +164,14 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
it('should match the default route', () => {
|
it('should match the default route', () => {
|
||||||
const chain1: RouteChain = [
|
const chain1: RouteChain = [
|
||||||
{ id: 'tabs', path: [''], props: undefined },
|
{ id: 'tabs', path: [''], params: undefined },
|
||||||
{ id: 'tab1', path: [''], props: undefined },
|
{ id: 'tab1', path: [''], params: undefined },
|
||||||
{ id: 'schedule', path: [''], props: undefined }
|
{ id: 'schedule', path: [''], params: undefined }
|
||||||
];
|
];
|
||||||
const chain2: RouteChain = [
|
const chain2: RouteChain = [
|
||||||
{ id: 'tabs', path: [''], props: undefined },
|
{ id: 'tabs', path: [''], params: undefined },
|
||||||
{ id: 'tab2', path: ['tab2'], props: undefined },
|
{ id: 'tab2', path: ['tab2'], params: undefined },
|
||||||
{ id: 'page2', path: [''], props: undefined }
|
{ id: 'page2', path: [''], params: undefined }
|
||||||
];
|
];
|
||||||
|
|
||||||
expect(routerPathToChain([''], [chain1])).toEqual({chain: chain1, matches: 3});
|
expect(routerPathToChain([''], [chain1])).toEqual({chain: chain1, matches: 3});
|
||||||
@ -162,20 +179,47 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
expect(routerPathToChain([''], [chain2])).toEqual({chain: null, matches: 0});
|
expect(routerPathToChain([''], [chain2])).toEqual({chain: null, matches: 0});
|
||||||
expect(routerPathToChain(['tab2'], [chain2])).toEqual({chain: chain2, matches: 3});
|
expect(routerPathToChain(['tab2'], [chain2])).toEqual({chain: chain2, matches: 3});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('mergeParams', () => {
|
||||||
|
it('should merge undefined', () => {
|
||||||
|
expect(mergeParams(undefined, undefined)).toBeUndefined();
|
||||||
|
expect(mergeParams(null, undefined)).toBeUndefined();
|
||||||
|
expect(mergeParams(undefined, null)).toBeUndefined();
|
||||||
|
expect(mergeParams(null, null)).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should merge undefined with params', () => {
|
||||||
|
const params = {data: '1'};
|
||||||
|
expect(mergeParams(undefined, params)).toEqual(params);
|
||||||
|
expect(mergeParams(null, params)).toEqual(params);
|
||||||
|
expect(mergeParams(params, undefined)).toEqual(params);
|
||||||
|
expect(mergeParams(params, null)).toEqual(params);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should merge params with params', () => {
|
||||||
|
const params1 = {data: '1', data3: 'hello'};
|
||||||
|
const params2 = {data: '2', data2: 'hola'};
|
||||||
|
|
||||||
|
expect(mergeParams(params1, params2)).toEqual({
|
||||||
|
data: '2',
|
||||||
|
data2: 'hola',
|
||||||
|
data3: 'hello'
|
||||||
|
});
|
||||||
|
expect(params1).toEqual({data: '1', data3: 'hello'});
|
||||||
|
expect(params2).toEqual({data: '2', data2: 'hola'});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('matchRoute', () => {
|
// describe('matchRoute', () => {
|
||||||
// it('should match simple route', () => {
|
// it('should match simple route', () => {
|
||||||
// const path = ['path', 'to', 'component'];
|
// const path = ['path', 'to', 'component'];
|
||||||
// const routes: RouteChain[] = [
|
// const routes: RouteChain[] = [
|
||||||
// [{ id: 2, path: ['to'], props: undefined }],
|
// [{ id: 2, path: ['to'], params: undefined }],
|
||||||
// [{ id: 1, path: ['path'], props: undefined }],
|
// [{ id: 1, path: ['path'], params: undefined }],
|
||||||
// [{ id: 3, path: ['segment'], props: undefined }],
|
// [{ id: 3, path: ['segment'], params: undefined }],
|
||||||
// [{ id: 4, path: [''], props: undefined }],
|
// [{ id: 4, path: [''], params: undefined }],
|
||||||
// ];
|
// ];
|
||||||
// const match = routerPathToChain(path, routes);
|
// const match = routerPathToChain(path, routes);
|
||||||
// expect(match).toEqual({ id: 1, path: ['path'], children: [] });
|
// expect(match).toEqual({ id: 1, path: ['path'], children: [] });
|
||||||
@ -184,10 +228,10 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
// it('should match default route', () => {
|
// it('should match default route', () => {
|
||||||
// const routes: RouteTree = [
|
// const routes: RouteTree = [
|
||||||
// { id: 2, path: ['to'], children: [], props: undefined },
|
// { id: 2, path: ['to'], children: [], params: undefined },
|
||||||
// { id: 1, path: ['path'], children: [], props: undefined },
|
// { id: 1, path: ['path'], children: [], params: undefined },
|
||||||
// { id: 3, path: ['segment'], children: [], props: undefined },
|
// { id: 3, path: ['segment'], children: [], params: undefined },
|
||||||
// { id: 4, path: [''], children: [], props: undefined },
|
// { id: 4, path: [''], children: [], params: undefined },
|
||||||
// ];
|
// ];
|
||||||
// const seg = new RouterSegments(['hola', 'path']);
|
// const seg = new RouterSegments(['hola', 'path']);
|
||||||
// let match = matchRoute(seg, routes);
|
// let match = matchRoute(seg, routes);
|
||||||
@ -204,10 +248,10 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
// it('should not match any route', () => {
|
// it('should not match any route', () => {
|
||||||
// const routes: RouteTree = [
|
// const routes: RouteTree = [
|
||||||
// { id: 2, path: ['to', 'to', 'to'], children: [], props: undefined },
|
// { id: 2, path: ['to', 'to', 'to'], children: [], params: undefined },
|
||||||
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
|
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
|
||||||
// { id: 3, path: ['hola', 'adam'], children: [], props: undefined },
|
// { id: 3, path: ['hola', 'adam'], children: [], params: undefined },
|
||||||
// { id: 4, path: [''], children: [], props: undefined },
|
// { id: 4, path: [''], children: [], params: undefined },
|
||||||
// ];
|
// ];
|
||||||
// const seg = new RouterSegments(['hola', 'manu', 'adam']);
|
// const seg = new RouterSegments(['hola', 'manu', 'adam']);
|
||||||
// const match = matchRoute(seg, routes);
|
// const match = matchRoute(seg, routes);
|
||||||
@ -224,8 +268,8 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
// it('should not match any route (2)', () => {
|
// it('should not match any route (2)', () => {
|
||||||
// const routes: RouteTree = [
|
// const routes: RouteTree = [
|
||||||
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
|
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
|
||||||
// { id: 3, path: ['hola', 'adam'], children: [], props: undefined },
|
// { id: 3, path: ['hola', 'adam'], children: [], params: undefined },
|
||||||
// ];
|
// ];
|
||||||
// const seg = new RouterSegments(['adam']);
|
// const seg = new RouterSegments(['adam']);
|
||||||
// expect(matchRoute(seg, routes)).toBeNull();
|
// expect(matchRoute(seg, routes)).toBeNull();
|
||||||
@ -235,10 +279,10 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
// it ('should match multiple segments', () => {
|
// it ('should match multiple segments', () => {
|
||||||
// const routes: RouteTree = [
|
// const routes: RouteTree = [
|
||||||
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
|
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
|
||||||
// { id: 2, path: ['manu', 'hello'], children: [], props: undefined },
|
// { id: 2, path: ['manu', 'hello'], children: [], params: undefined },
|
||||||
// { id: 3, path: ['hello'], children: [], props: undefined },
|
// { id: 3, path: ['hello'], children: [], params: undefined },
|
||||||
// { id: 4, path: [''], children: [], props: undefined },
|
// { id: 4, path: [''], children: [], params: undefined },
|
||||||
// ];
|
// ];
|
||||||
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'manu', 'hello']);
|
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'manu', 'hello']);
|
||||||
// let match = matchRoute(seg, routes);
|
// let match = matchRoute(seg, routes);
|
||||||
@ -259,9 +303,9 @@ describe('routerPathToChain', () => {
|
|||||||
|
|
||||||
// it('should match long multi segments', () => {
|
// it('should match long multi segments', () => {
|
||||||
// const routes: RouteTree = [
|
// const routes: RouteTree = [
|
||||||
// { id: 1, path: ['adam', 'manu', 'hello', 'menu', 'hello'], children: [], props: undefined },
|
// { id: 1, path: ['adam', 'manu', 'hello', 'menu', 'hello'], children: [], params: undefined },
|
||||||
// { id: 2, path: ['adam', 'manu', 'hello', 'menu'], children: [], props: undefined },
|
// { id: 2, path: ['adam', 'manu', 'hello', 'menu'], children: [], params: undefined },
|
||||||
// { id: 3, path: ['adam', 'manu'], children: [], props: undefined },
|
// { id: 3, path: ['adam', 'manu'], children: [], params: undefined },
|
||||||
// ];
|
// ];
|
||||||
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'menu', 'hello']);
|
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'menu', 'hello']);
|
||||||
// const match = matchRoute(seg, routes);
|
// const match = matchRoute(seg, routes);
|
||||||
|
@ -11,18 +11,20 @@ export function writeNavState(root: HTMLElement, chain: RouteChain, index: numbe
|
|||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
return node.componentOnReady()
|
return node.componentOnReady()
|
||||||
.then(() => node.setRouteId(route.id, route.props, direction))
|
.then(() => node.setRouteId(route.id, route.params, direction))
|
||||||
.then(changed => {
|
.then(changed => {
|
||||||
if (changed) {
|
if (changed) {
|
||||||
direction = 0;
|
direction = 0;
|
||||||
}
|
}
|
||||||
const nextEl = node.getContentElement();
|
const nextEl = node.getContentElement();
|
||||||
if (nextEl) {
|
const promise = (nextEl)
|
||||||
return writeNavState(nextEl, chain, index + 1, direction)
|
? writeNavState(nextEl, chain, index + 1, direction)
|
||||||
.then(() => node.markVisible());
|
: Promise.resolve();
|
||||||
} else {
|
|
||||||
return node.markVisible();
|
if (node.markVisible) {
|
||||||
|
return promise.then(() => node.markVisible());
|
||||||
}
|
}
|
||||||
|
return promise;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
export interface NavOutlet {
|
export interface NavOutlet {
|
||||||
setRouteId(id: any, data: any, direction: number): Promise<boolean>;
|
setRouteId(id: any, data: any, direction: number): Promise<boolean>;
|
||||||
markVisible(): Promise<void>;
|
markVisible?(): Promise<void>;
|
||||||
getRouteId(): string;
|
getRouteId(): string;
|
||||||
|
|
||||||
getContentElement(): HTMLElement | null;
|
getContentElement(): HTMLElement | null;
|
||||||
@ -17,7 +17,7 @@ export type NavOutletElement = NavOutlet & HTMLStencilElement;
|
|||||||
export interface RouteEntry {
|
export interface RouteEntry {
|
||||||
id: string;
|
id: string;
|
||||||
path: string[];
|
path: string[];
|
||||||
props: any|undefined;
|
params: any|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RouteNode extends RouteEntry {
|
export interface RouteNode extends RouteEntry {
|
||||||
|
@ -13,26 +13,61 @@ export function matchesIDs(ids: string[], chain: RouteChain): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function matchesPath(path: string[], chain: RouteChain): boolean {
|
export function matchesPath(path: string[], chain: RouteChain): RouteChain | null {
|
||||||
const segments = new RouterSegments(path);
|
const segments = new RouterSegments(path);
|
||||||
let matchesDefault = false;
|
let matchesDefault = false;
|
||||||
|
let allparams: any[];
|
||||||
for (let i = 0; i < chain.length; i++) {
|
for (let i = 0; i < chain.length; i++) {
|
||||||
const route = chain[i];
|
const path = chain[i].path;
|
||||||
if (route.path[0] !== '') {
|
if (path[0] === '') {
|
||||||
for (const segment of route.path) {
|
matchesDefault = true;
|
||||||
if (segments.next() !== segment) {
|
} else {
|
||||||
return false;
|
for (const segment of path) {
|
||||||
|
const data = segments.next();
|
||||||
|
// data param
|
||||||
|
if (segment[0] === ':') {
|
||||||
|
if (data === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
allparams = allparams || [];
|
||||||
|
const params = allparams[i] || (allparams[i] = {});
|
||||||
|
params[segment.slice(1)] = data;
|
||||||
|
} else if (data !== segment) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matchesDefault = false;
|
matchesDefault = false;
|
||||||
} else {
|
|
||||||
matchesDefault = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (matchesDefault) {
|
const matches = (matchesDefault)
|
||||||
return matchesDefault === segments.isDefault();
|
? matchesDefault === segments.isDefault()
|
||||||
|
: true;
|
||||||
|
|
||||||
|
if (!matches) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return true;
|
if (allparams) {
|
||||||
|
return chain.map((route, i) => ({
|
||||||
|
id: route.id,
|
||||||
|
path: route.path,
|
||||||
|
params: mergeParams(route.params, allparams[i])
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mergeParams(a: any, b: any): any {
|
||||||
|
if (!a && b) {
|
||||||
|
return b;
|
||||||
|
} else if (a && !b) {
|
||||||
|
return a;
|
||||||
|
} else if (a && b) {
|
||||||
|
return {
|
||||||
|
...a,
|
||||||
|
...b
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -48,7 +83,7 @@ export function routerIDsToChain(ids: string[], chains: RouteChain[]): RouteMatc
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
chain: match,
|
chain: match,
|
||||||
matches: maxMatches,
|
matches: maxMatches
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,10 +92,11 @@ export function routerPathToChain(path: string[], chains: RouteChain[]): RouteMa
|
|||||||
let match: RouteChain = null;
|
let match: RouteChain = null;
|
||||||
let matches = 0;
|
let matches = 0;
|
||||||
for (const chain of chains) {
|
for (const chain of chains) {
|
||||||
if (matchesPath(path, chain)) {
|
const matchedChain = matchesPath(path, chain);
|
||||||
if (chain.length > matches) {
|
if (matchedChain !== null) {
|
||||||
matches = chain.length;
|
if (matchedChain.length > matches) {
|
||||||
match = chain;
|
matches = matchedChain.length;
|
||||||
|
match = matchedChain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ export function readRoutes(root: Element): RouteTree {
|
|||||||
.map(el => ({
|
.map(el => ({
|
||||||
path: parsePath(readProp(el, 'path')),
|
path: parsePath(readProp(el, 'path')),
|
||||||
id: readProp(el, 'component'),
|
id: readProp(el, 'component'),
|
||||||
props: readProp(el, 'props'),
|
params: el.params,
|
||||||
children: readRoutes(el)
|
children: readRoutes(el)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ function flattenNode(chain: RouteChain, routes: RouteChain[], node: RouteNode) {
|
|||||||
s.push({
|
s.push({
|
||||||
id: node.id,
|
id: node.id,
|
||||||
path: node.path,
|
path: node.path,
|
||||||
props: node.props
|
params: node.params
|
||||||
});
|
});
|
||||||
|
|
||||||
if (node.children.length === 0) {
|
if (node.children.length === 0) {
|
||||||
|
Reference in New Issue
Block a user