mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c36b1fd2dc |
@@ -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)
|
||||
|
||||
|
||||
@@ -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')`.
|
||||
|
||||
|
||||
2
packages/core/package-lock.json
generated
2
packages/core/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "0.1.4-2",
|
||||
"version": "0.1.4-1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "0.1.4-2",
|
||||
"version": "0.1.4-1",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
|
||||
3
packages/core/src/components.d.ts
vendored
3
packages/core/src/components.d.ts
vendored
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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'`.
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -223,6 +223,11 @@ export class NavControllerBase implements NavOutlet {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Method()
|
||||
markVisible() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Method()
|
||||
getContentElement(): HTMLElement {
|
||||
const active = this.getActive();
|
||||
|
||||
@@ -71,6 +71,9 @@ Return a view controller
|
||||
#### insertPages()
|
||||
|
||||
|
||||
#### markVisible()
|
||||
|
||||
|
||||
#### pop()
|
||||
|
||||
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
string
|
||||
|
||||
|
||||
#### params
|
||||
|
||||
|
||||
|
||||
|
||||
#### path
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### props
|
||||
|
||||
any
|
||||
|
||||
|
||||
## Attributes
|
||||
|
||||
#### component
|
||||
@@ -29,16 +29,16 @@ string
|
||||
string
|
||||
|
||||
|
||||
#### params
|
||||
|
||||
|
||||
|
||||
|
||||
#### path
|
||||
|
||||
string
|
||||
|
||||
|
||||
#### props
|
||||
|
||||
any
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
||||
|
||||
@@ -7,5 +7,5 @@ import { Component, Prop } from '@stencil/core';
|
||||
export class Route {
|
||||
@Prop() path = '';
|
||||
@Prop() component: string;
|
||||
@Prop() params: undefined;
|
||||
@Prop() props: any = {};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user