Compare commits

..

1 Commits

Author SHA1 Message Date
Brandy Carney
c36b1fd2dc @ionic/core 0.1.4-1 2018-03-07 17:59:13 -05:00
20 changed files with 151 additions and 285 deletions

View File

@@ -1,25 +1,3 @@
<a name="0.1.4-2"></a>
## [0.1.4-2](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-2) (2018-03-07)
### Bug Fixes
* **fab:** add side as a property for fab list ([7387d34](https://github.com/ionic-team/ionic/commit/7387d34))
* **ion-router:** fixes routing algorithm ([c8a27b7](https://github.com/ionic-team/ionic/commit/c8a27b7))
* **item:** href ([540c33b](https://github.com/ionic-team/ionic/commit/540c33b))
* **overlays:** bundling of overlays ([9650bec](https://github.com/ionic-team/ionic/commit/9650bec))
* **router:** invalid url ([c7fe694](https://github.com/ionic-team/ionic/commit/c7fe694))
* **routing:** flickering (part 1) ([7b264f9](https://github.com/ionic-team/ionic/commit/7b264f9))
* **tabs:** do not select when using router ([174d9b5](https://github.com/ionic-team/ionic/commit/174d9b5))
### Features
* **router:** adds parameters ([f29e3f4](https://github.com/ionic-team/ionic/commit/f29e3f4))
* **virtual-scroll:** adds JSX support ([dc8b363](https://github.com/ionic-team/ionic/commit/dc8b363))
<a name="0.1.4-1"></a>
## [0.1.4-1](https://github.com/ionic-team/ionic/compare/v0.1.4-0...v0.1.4-1) (2018-03-07)

View File

@@ -20,7 +20,7 @@ The Ionic Core package contains the Web Components that make up the reusable UI
Easiest way to start using Ionic Core is by adding a script tag to the CDN:
<script src="https://unpkg.com/@ionic/core@0.1.4-2/dist/ionic.js"></script>
<script src="https://unpkg.com/@ionic/core@0.1.4-1/dist/ionic.js"></script>
Any Ionic component added to the webpage will automatically load. This includes writing the component tag directly in HTML, or using JavaScript such as `document.createElement('ion-toggle')`.

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "0.1.4-2",
"version": "0.1.4-1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "0.1.4-2",
"version": "0.1.4-1",
"description": "Base components for Ionic",
"keywords": [
"ionic",

View File

@@ -908,7 +908,6 @@ declare global {
namespace JSXElements {
export interface IonFabListAttributes extends HTMLAttributes {
activated?: boolean;
side?: 'left' | 'right' | 'top' | 'bottom';
}
}
}
@@ -2601,8 +2600,8 @@ declare global {
namespace JSXElements {
export interface IonRouteAttributes extends HTMLAttributes {
component?: string;
params?: undefined;
path?: string;
props?: any;
}
}
}

View File

@@ -13,10 +13,6 @@ import { CssClassMap } from '../../index';
export class FabButton {
@Element() private el: HTMLElement;
@State() private inContainer = false;
@State() private inList = false;
/**
* The color to use from your Sass `$colors` map.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
@@ -31,16 +27,6 @@ export class FabButton {
*/
@Prop() mode: 'ios' | 'md';
/**
* If true, the fab button will be show a close icon. Defaults to `false`.
*/
@Prop() activated = false;
/**
* If true, the user cannot interact with the fab button. Defaults to `false`.
*/
@Prop() disabled = false;
/**
* Contains a URL or a URL fragment that the hyperlink points to.
* If this property is set, an anchor tag will be rendered.
@@ -52,10 +38,18 @@ export class FabButton {
*/
@Prop() translucent = false;
@Prop() activated = false;
@Prop() toggleActive: Function;
@Prop() show = false;
@State() private inContainer = false;
@State() private inList = false;
/**
* If true, the user cannot interact with the fab button. Defaults to `false`.
*/
@Prop() disabled = false;
componentDidLoad() {
const parentNode = this.el.parentNode;
@@ -80,6 +74,7 @@ export class FabButton {
'fab-button-in-list': this.inList,
[`fab-button-${this.mode}-in-list`]: this.inList,
[`fab-button-translucent-${this.mode}-in-list`]: (this.inList && this.translucent),
'fab-button-close-active': this.activated,
'fab-button-show': this.show,
};

View File

@@ -42,8 +42,6 @@ If the FAB button is not wrapped with `<ion-fab>`, it will scroll with the conte
boolean
If true, the fab button will be show a close icon. Defaults to `false`.
#### color
@@ -101,8 +99,6 @@ If true, the fab button will be translucent. Defaults to `false`.
boolean
If true, the fab button will be show a close icon. Defaults to `false`.
#### color

View File

@@ -38,26 +38,26 @@ ion-fab-list {
transform: scale(1);
}
.fab-list-side-left .fab-button-in-list,
.fab-list-side-right .fab-button-in-list {
ion-fab-list[side=left] .fab-button-in-list,
ion-fab-list[side=right] .fab-button-in-list {
@include margin(0, 8px);
}
.fab-list-side-top {
ion-fab-list[side=top] {
top: auto;
bottom: 0;
flex-direction: column-reverse;
}
.fab-list-side-left {
ion-fab-list[side=left] {
@include margin(0, $fab-size + $fab-list-margin);
@include position-horizontal(null, 0);
flex-direction: row-reverse;
}
.fab-list-side-right {
ion-fab-list[side=right] {
@include margin(0, $fab-size + $fab-list-margin);
@include position(null, null, null, 0);

View File

@@ -8,9 +8,6 @@ import { Component, Element, Prop, Watch } from '@stencil/core';
export class FabList {
@Element() private el: HTMLIonFabElement;
/**
* If true, the fab list will be show all fab buttons in the list. Defaults to `false`.
*/
@Prop() activated = false;
@Watch('activated')
@@ -25,17 +22,10 @@ export class FabList {
}
}
/**
* The side the fab list will show on relative to the main fab button. Defaults to `'bottom'`.
*/
@Prop() side: 'left' | 'right' | 'top' | 'bottom' = 'bottom';
hostData() {
return {
class: {
'fab-list-active': this.activated,
[`fab-list-side-${this.side}`]: this.side
'fab-list-active': this.activated
}
};
}

View File

@@ -33,15 +33,6 @@ The `ion-fab-list` element is a container for multiple FAB buttons. This collect
boolean
If true, the fab list will be show all fab buttons in the list. Defaults to `false`.
#### side
The side the fab list will show on relative to the main fab button. Defaults to `'bottom'`.
## Attributes
@@ -49,15 +40,6 @@ The side the fab list will show on relative to the main fab button. Defaults to
boolean
If true, the fab list will be show all fab buttons in the list. Defaults to `false`.
#### side
The side the fab list will show on relative to the main fab button. Defaults to `'bottom'`.
----------------------------------------------

View File

@@ -110,7 +110,7 @@ export class Item {
}
const attrs = (TagType === 'button')
? {type: 'button'}
: {href: this.href};
: {};
const showDetail = this.detail != null ? this.detail : (this.mode === 'ios' && clickable);

View File

@@ -223,6 +223,11 @@ export class NavControllerBase implements NavOutlet {
return null;
}
@Method()
markVisible() {
return Promise.resolve();
}
@Method()
getContentElement(): HTMLElement {
const active = this.getActive();

View File

@@ -71,6 +71,9 @@ Return a view controller
#### insertPages()
#### markVisible()
#### pop()

View File

@@ -12,16 +12,16 @@
string
#### params
#### path
string
#### props
any
## Attributes
#### component
@@ -29,16 +29,16 @@ string
string
#### params
#### path
string
#### props
any
----------------------------------------------

View File

@@ -7,5 +7,5 @@ import { Component, Prop } from '@stencil/core';
export class Route {
@Prop() path = '';
@Prop() component: string;
@Prop() params: undefined;
@Prop() props: any = {};
}

View File

@@ -1,30 +1,31 @@
import { RouteChain } from '../utils/interfaces';
import { matchesIDs, matchesPath, mergeParams, routerPathToChain } from '../utils/matching';
import { parsePath } from '../utils/path';
import { matchesIDs, matchesPath, routerPathToChain } from '../utils/matching';
import { mockRouteElement } from './parser.spec';
import { mockElement } from '@stencil/core/dist/testing';
const CHAIN_1: RouteChain = [
{ id: '2', path: ['to'], params: undefined },
{ id: '1', path: ['path'], params: undefined },
{ id: '3', path: ['segment'], params: undefined },
{ id: '4', path: [''], params: undefined },
{ id: '2', path: ['to'], props: undefined },
{ id: '1', path: ['path'], props: undefined },
{ id: '3', path: ['segment'], props: undefined },
{ id: '4', path: [''], props: undefined },
];
const CHAIN_2: RouteChain = [
{ id: '2', path: [''], params: undefined },
{ id: '1', path: [''], params: undefined },
{ id: '3', path: ['segment', 'to'], params: undefined },
{ id: '4', path: [''], params: undefined },
{ id: '5', path: ['hola'], params: undefined },
{ id: '6', path: [''], params: undefined },
{ id: '7', path: [''], params: undefined },
{ id: '8', path: ['adios', 'que', 'tal'], params: undefined },
{ id: '2', path: [''], props: undefined },
{ id: '1', path: [''], props: undefined },
{ id: '3', path: ['segment', 'to'], props: undefined },
{ id: '4', path: [''], props: undefined },
{ id: '5', path: ['hola'], props: undefined },
{ id: '6', path: [''], props: undefined },
{ id: '7', path: [''], props: undefined },
{ id: '8', path: ['adios', 'que', 'tal'], props: undefined },
];
const CHAIN_3: RouteChain = [
{ id: '2', path: ['this', 'to'], params: undefined },
{ id: '1', path: ['path'], params: undefined },
{ id: '3', path: ['segment', 'to', 'element'], params: undefined },
{ id: '4', path: [''], params: undefined },
{ id: '2', path: ['this', 'to'], props: undefined },
{ id: '1', path: ['path'], props: undefined },
{ id: '3', path: ['segment', 'to', 'element'], props: undefined },
{ id: '4', path: [''], props: undefined },
];
@@ -46,85 +47,67 @@ describe('matchesIDs', () => {
describe('matchesPath', () => {
it('should match simple path', () => {
const chain: RouteChain = CHAIN_3;
expect(matchesPath(['this'], chain)).toEqual(null);
expect(matchesPath(['this', 'to'], chain)).toEqual(null);
expect(matchesPath(['this', 'to', 'path'], chain)).toEqual(null);
expect(matchesPath(['this', 'to', 'path', 'segment'], chain)).toEqual(null);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to'], chain)).toEqual(null);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element'], chain)).toEqual(chain);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element', 'more'], chain)).toEqual(null);
expect(matchesPath(['this'], chain)).toBe(false);
expect(matchesPath(['this', 'to'], chain)).toBe(false);
expect(matchesPath(['this', 'to', 'path'], chain)).toBe(false);
expect(matchesPath(['this', 'to', 'path', 'segment'], chain)).toBe(false);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to'], chain)).toBe(false);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element'], chain)).toBe(true);
expect(matchesPath(['this', 'to', 'path', 'segment', 'to', 'element', 'more'], chain)).toBe(false);
expect(matchesPath([], chain)).toEqual(null);
expect(matchesPath([''], chain)).toEqual(null);
expect(matchesPath(['path'], chain)).toEqual(null);
expect(matchesPath([], chain)).toBe(false);
expect(matchesPath([''], chain)).toBe(false);
expect(matchesPath(['path'], chain)).toBe(false);
});
it('should match simple default route', () => {
const chain: RouteChain = CHAIN_2;
expect(matchesPath([''], chain)).toEqual(null);
expect(matchesPath(['segment'], chain)).toEqual(null);
expect(matchesPath(['segment', 'to'], chain)).toEqual(null);
expect(matchesPath(['segment', 'to', 'hola'], chain)).toEqual(null);
expect(matchesPath(['segment', 'to', 'hola', 'adios'], chain)).toEqual(null);
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que'], chain)).toEqual(null);
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([''], chain)).toBe(false);
expect(matchesPath(['segment'], chain)).toBe(false);
expect(matchesPath(['segment', 'to'], chain)).toBe(false);
expect(matchesPath(['segment', 'to', 'hola'], chain)).toBe(false);
expect(matchesPath(['segment', 'to', 'hola', 'adios'], chain)).toBe(false);
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que'], chain)).toBe(false);
expect(matchesPath(['segment', 'to', 'hola', 'adios', 'que', 'tal'], chain)).toBe(true);
expect(matchesPath(['to'], chain)).toEqual(null);
expect(matchesPath(['path', 'to'], chain)).toEqual(null);
expect(matchesPath(['to'], chain)).toBe(false);
expect(matchesPath(['path', 'to'], chain)).toBe(false);
});
it('should match simple route 2', () => {
const chain: RouteChain = [{ id: '5', path: ['hola'], params: undefined }];
expect(matchesPath([''], chain)).toEqual(null);
expect(matchesPath(['hola'], chain)).toEqual(chain);
expect(matchesPath(['hola', 'hola'], chain)).toEqual(chain);
expect(matchesPath(['hola', 'adios'], chain)).toEqual(chain);
const chain: RouteChain = [{ id: '5', path: ['hola'], props: undefined }];
expect(matchesPath([''], chain)).toBe(false);
expect(matchesPath(['hola'], chain)).toBe(true);
expect(matchesPath(['hola', 'hola'], chain)).toBe(true);
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
});
it('should match simple route 3', () => {
const chain: RouteChain = [{ id: '5', path: ['hola', 'adios'], params: undefined }];
expect(matchesPath([''], chain)).toEqual(null);
expect(matchesPath(['hola'], chain)).toEqual(null);
expect(matchesPath(['hola', 'hola'], chain)).toEqual(null);
expect(matchesPath(['hola', 'adios'], chain)).toEqual(chain);
expect(matchesPath(['hola', 'adios', 'bye'], chain)).toEqual(chain);
const chain: RouteChain = [{ id: '5', path: ['hola', 'adios'], props: undefined }];
expect(matchesPath([''], chain)).toBe(false);
expect(matchesPath(['hola'], chain)).toBe(false);
expect(matchesPath(['hola', 'hola'], chain)).toBe(false);
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
});
it('should match simple route 4', () => {
const chain: RouteChain = [
{ id: '5', path: ['hola'], params: undefined },
{ id: '5', path: ['adios'], params: undefined }];
{ id: '5', path: ['hola'], props: undefined },
{ id: '5', path: ['adios'], props: undefined }];
expect(matchesPath([''], chain)).toEqual(null);
expect(matchesPath(['hola'], chain)).toEqual(null);
expect(matchesPath(['hola', 'hola'], chain)).toEqual(null);
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'} },
]);
expect(matchesPath([''], chain)).toBe(false);
expect(matchesPath(['hola'], chain)).toBe(false);
expect(matchesPath(['hola', 'hola'], chain)).toBe(false);
expect(matchesPath(['hola', 'adios'], chain)).toBe(true);
});
});
describe('routerPathToChain', () => {
it('should match the route with higher priority', () => {
const chain3: RouteChain = [{ id: '5', path: ['hola'], params: undefined }];
const chain3: RouteChain = [{ id: '5', path: ['hola'], props: undefined }];
const chain4: RouteChain = [
{ id: '5', path: ['hola'], params: undefined },
{ id: '5', path: ['adios'], params: undefined }];
{ id: '5', path: ['hola'], props: undefined },
{ id: '5', path: ['adios'], props: undefined }];
const routes: RouteChain[] = [
CHAIN_1,
@@ -164,14 +147,14 @@ describe('routerPathToChain', () => {
it('should match the default route', () => {
const chain1: RouteChain = [
{ id: 'tabs', path: [''], params: undefined },
{ id: 'tab1', path: [''], params: undefined },
{ id: 'schedule', path: [''], params: undefined }
{ id: 'tabs', path: [''], props: undefined },
{ id: 'tab1', path: [''], props: undefined },
{ id: 'schedule', path: [''], props: undefined }
];
const chain2: RouteChain = [
{ id: 'tabs', path: [''], params: undefined },
{ id: 'tab2', path: ['tab2'], params: undefined },
{ id: 'page2', path: [''], params: undefined }
{ id: 'tabs', path: [''], props: undefined },
{ id: 'tab2', path: ['tab2'], props: undefined },
{ id: 'page2', path: [''], props: undefined }
];
expect(routerPathToChain([''], [chain1])).toEqual({chain: chain1, matches: 3});
@@ -179,47 +162,20 @@ describe('routerPathToChain', () => {
expect(routerPathToChain([''], [chain2])).toEqual({chain: null, matches: 0});
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', () => {
// it('should match simple route', () => {
// const path = ['path', 'to', 'component'];
// const routes: RouteChain[] = [
// [{ id: 2, path: ['to'], params: undefined }],
// [{ id: 1, path: ['path'], params: undefined }],
// [{ id: 3, path: ['segment'], params: undefined }],
// [{ id: 4, path: [''], params: undefined }],
// [{ id: 2, path: ['to'], props: undefined }],
// [{ id: 1, path: ['path'], props: undefined }],
// [{ id: 3, path: ['segment'], props: undefined }],
// [{ id: 4, path: [''], props: undefined }],
// ];
// const match = routerPathToChain(path, routes);
// expect(match).toEqual({ id: 1, path: ['path'], children: [] });
@@ -228,10 +184,10 @@ describe('mergeParams', () => {
// it('should match default route', () => {
// const routes: RouteTree = [
// { id: 2, path: ['to'], children: [], params: undefined },
// { id: 1, path: ['path'], children: [], params: undefined },
// { id: 3, path: ['segment'], children: [], params: undefined },
// { id: 4, path: [''], children: [], params: undefined },
// { id: 2, path: ['to'], children: [], props: undefined },
// { id: 1, path: ['path'], children: [], props: undefined },
// { id: 3, path: ['segment'], children: [], props: undefined },
// { id: 4, path: [''], children: [], props: undefined },
// ];
// const seg = new RouterSegments(['hola', 'path']);
// let match = matchRoute(seg, routes);
@@ -248,10 +204,10 @@ describe('mergeParams', () => {
// it('should not match any route', () => {
// const routes: RouteTree = [
// { id: 2, path: ['to', 'to', 'to'], children: [], params: undefined },
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
// { id: 3, path: ['hola', 'adam'], children: [], params: undefined },
// { id: 4, path: [''], children: [], params: undefined },
// { id: 2, path: ['to', 'to', 'to'], children: [], props: undefined },
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
// { id: 3, path: ['hola', 'adam'], children: [], props: undefined },
// { id: 4, path: [''], children: [], props: undefined },
// ];
// const seg = new RouterSegments(['hola', 'manu', 'adam']);
// const match = matchRoute(seg, routes);
@@ -268,8 +224,8 @@ describe('mergeParams', () => {
// it('should not match any route (2)', () => {
// const routes: RouteTree = [
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
// { id: 3, path: ['hola', 'adam'], children: [], params: undefined },
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
// { id: 3, path: ['hola', 'adam'], children: [], props: undefined },
// ];
// const seg = new RouterSegments(['adam']);
// expect(matchRoute(seg, routes)).toBeNull();
@@ -279,10 +235,10 @@ describe('mergeParams', () => {
// it ('should match multiple segments', () => {
// const routes: RouteTree = [
// { id: 1, path: ['adam', 'manu'], children: [], params: undefined },
// { id: 2, path: ['manu', 'hello'], children: [], params: undefined },
// { id: 3, path: ['hello'], children: [], params: undefined },
// { id: 4, path: [''], children: [], params: undefined },
// { id: 1, path: ['adam', 'manu'], children: [], props: undefined },
// { id: 2, path: ['manu', 'hello'], children: [], props: undefined },
// { id: 3, path: ['hello'], children: [], props: undefined },
// { id: 4, path: [''], children: [], props: undefined },
// ];
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'manu', 'hello']);
// let match = matchRoute(seg, routes);
@@ -303,9 +259,9 @@ describe('mergeParams', () => {
// it('should match long multi segments', () => {
// const routes: RouteTree = [
// { id: 1, path: ['adam', 'manu', 'hello', 'menu', 'hello'], children: [], params: undefined },
// { id: 2, path: ['adam', 'manu', 'hello', 'menu'], children: [], params: undefined },
// { id: 3, path: ['adam', 'manu'], children: [], params: undefined },
// { id: 1, path: ['adam', 'manu', 'hello', 'menu', 'hello'], children: [], props: undefined },
// { id: 2, path: ['adam', 'manu', 'hello', 'menu'], children: [], props: undefined },
// { id: 3, path: ['adam', 'manu'], children: [], props: undefined },
// ];
// const seg = new RouterSegments(['adam', 'manu', 'hello', 'menu', 'hello']);
// const match = matchRoute(seg, routes);

View File

@@ -1,8 +1,8 @@
import { breadthFirstSearch } from './common';
import { NavOutlet, RouteChain } from './interfaces';
export function writeNavState(root: HTMLElement, chain: RouteChain|null, index: number, direction: number): Promise<void> {
if (!chain || index >= chain.length) {
export function writeNavState(root: HTMLElement, chain: RouteChain, index: number, direction: number): Promise<void> {
if (index >= chain.length) {
return Promise.resolve();
}
const route = chain[index];
@@ -11,20 +11,18 @@ export function writeNavState(root: HTMLElement, chain: RouteChain|null, index:
return Promise.resolve();
}
return node.componentOnReady()
.then(() => node.setRouteId(route.id, route.params, direction))
.then(() => node.setRouteId(route.id, route.props, direction))
.then(changed => {
if (changed) {
direction = 0;
}
const nextEl = node.getContentElement();
const promise = (nextEl)
? writeNavState(nextEl, chain, index + 1, direction)
: Promise.resolve();
if (node.markVisible) {
return promise.then(() => node.markVisible());
if (nextEl) {
return writeNavState(nextEl, chain, index + 1, direction)
.then(() => node.markVisible());
} else {
return node.markVisible();
}
return promise;
});
}

View File

@@ -1,7 +1,7 @@
export interface NavOutlet {
setRouteId(id: any, data: any, direction: number): Promise<boolean>;
markVisible?(): Promise<void>;
markVisible(): Promise<void>;
getRouteId(): string;
getContentElement(): HTMLElement | null;
@@ -17,7 +17,7 @@ export type NavOutletElement = NavOutlet & HTMLStencilElement;
export interface RouteEntry {
id: string;
path: string[];
params: any|undefined;
props: any|undefined;
}
export interface RouteNode extends RouteEntry {

View File

@@ -13,61 +13,26 @@ export function matchesIDs(ids: string[], chain: RouteChain): number {
}
export function matchesPath(path: string[], chain: RouteChain): RouteChain | null {
export function matchesPath(path: string[], chain: RouteChain): boolean {
const segments = new RouterSegments(path);
let matchesDefault = false;
let allparams: any[];
for (let i = 0; i < chain.length; i++) {
const path = chain[i].path;
if (path[0] === '') {
matchesDefault = true;
} else {
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;
const route = chain[i];
if (route.path[0] !== '') {
for (const segment of route.path) {
if (segments.next() !== segment) {
return false;
}
}
matchesDefault = false;
} else {
matchesDefault = true;
}
}
const matches = (matchesDefault)
? matchesDefault === segments.isDefault()
: true;
if (!matches) {
return null;
if (matchesDefault) {
return matchesDefault === segments.isDefault();
}
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;
return true;
}
@@ -83,7 +48,7 @@ export function routerIDsToChain(ids: string[], chains: RouteChain[]): RouteMatc
}
return {
chain: match,
matches: maxMatches
matches: maxMatches,
};
}
@@ -92,11 +57,10 @@ export function routerPathToChain(path: string[], chains: RouteChain[]): RouteMa
let match: RouteChain = null;
let matches = 0;
for (const chain of chains) {
const matchedChain = matchesPath(path, chain);
if (matchedChain !== null) {
if (matchedChain.length > matches) {
matches = matchedChain.length;
match = matchedChain;
if (matchesPath(path, chain)) {
if (chain.length > matches) {
matches = chain.length;
match = chain;
}
}
}

View File

@@ -8,7 +8,7 @@ export function readRoutes(root: Element): RouteTree {
.map(el => ({
path: parsePath(readProp(el, 'path')),
id: readProp(el, 'component'),
params: el.params,
props: readProp(el, 'props'),
children: readRoutes(el)
}));
}
@@ -36,7 +36,7 @@ function flattenNode(chain: RouteChain, routes: RouteChain[], node: RouteNode) {
s.push({
id: node.id,
path: node.path,
params: node.params
props: node.props
});
if (node.children.length === 0) {