refactor(nav): usign enums

This commit is contained in:
Manu Mtz.-Almeida
2018-03-11 01:18:08 +01:00
parent 22f6a34f5b
commit cadcab9b40
4 changed files with 55 additions and 151 deletions

View File

@@ -2,14 +2,6 @@ import { ViewController, isViewController } from './view-controller';
import { NavControllerBase } from './nav';
import { Transition } from './transition';
export type NavParams = {[key: string]: any};
export interface PageMeta {
page: string | HTMLElement | ViewController;
params?: any;
}
export function convertToView(page: any, params: any): ViewController {
if (!page) {
return null;
@@ -21,27 +13,25 @@ export function convertToView(page: any, params: any): ViewController {
}
export function convertToViews(pages: any[]): ViewController[] {
return pages
.map(page => {
if (isViewController(page)) {
return page;
}
if ('page' in page) {
return convertToView(page.page, page.params);
}
return convertToView(page, undefined);
})
.filter(v => v !== null);
return pages.map(page => {
if (isViewController(page)) {
return page;
}
if ('page' in page) {
return convertToView(page.page, page.params);
}
return convertToView(page, undefined);
})
.filter(v => v !== null);
}
export function setZIndex(nav: NavControllerBase, enteringView: ViewController, leavingView: ViewController, direction: string) {
if (enteringView) {
leavingView = leavingView || nav.getPrevious(enteringView);
if (leavingView && isPresent(leavingView._zIndex)) {
if (direction === DIRECTION_BACK) {
if (direction === NavDirection.back) {
enteringView._setZIndex(leavingView._zIndex - 1);
} else {
@@ -54,43 +44,25 @@ export function setZIndex(nav: NavControllerBase, enteringView: ViewController,
}
}
export function isTabs(nav: any): boolean {
// Tabs (ion-tabs)
return !!nav && !!nav.getSelected;
export function isPresent(val: any): val is any {
return val !== undefined && val !== null;
}
export function isTab(nav: any): boolean {
// Tab (ion-tab)
return !!nav && isPresent(nav._tabId);
export const enum ViewState {
New = 1,
Initialized,
Attached,
Destroyed
}
export function isNav(nav: any): boolean {
// Nav (ion-nav), Tab (ion-tab), Portal (ion-portal)
return !!nav && !!nav.push && nav.getType() === 'nav';
export const enum NavDirection {
back = 'back',
forward = 'forward'
}
export function linkToSegment(navId: string, type: string, secondaryId: string, link: NavLink): NavSegment {
const segment = <NavSegment> Object.assign({}, link);
segment.navId = navId;
segment.type = type;
segment.secondaryId = secondaryId;
return segment;
}
export const INIT_ZINDEX = 100;
// internal link interface, not exposed publicly
export interface NavLink {
component?: any;
loadChildren?: string;
name?: string;
segment?: string;
segmentParts?: string[];
segmentPartsLen?: number;
staticLen?: number;
dataLen?: number;
dataKeys?: {[key: string]: boolean};
defaultHistory?: any[];
}
export type NavParams = {[key: string]: any};
export interface NavResult {
hasCompleted: boolean;
@@ -100,36 +72,6 @@ export interface NavResult {
direction?: string;
}
export interface NavSegment extends DehydratedSegment {
type: string;
navId: string;
secondaryId: string;
requiresExplicitNavPrefix?: boolean;
}
export interface DehydratedSegment {
id: string;
name: string;
component?: any;
loadChildren?: string;
data: any;
defaultHistory?: NavSegment[];
secondaryId?: string;
}
export interface DehydratedSegmentPair {
segments: DehydratedSegment[];
navGroup: NavGroup;
}
export interface NavGroup {
type: string;
navId: string;
secondaryId: string;
segmentPieces?: string[];
tabSegmentPieces?: string[];
}
export interface NavOptions {
animate?: boolean;
animation?: string;
@@ -147,8 +89,6 @@ export interface NavOptions {
viewIsReady?: () => Promise<any>;
}
export function isPresent(val: any): val is any { return val !== undefined && val !== null; }
export interface Page extends Function {
new (...args: any[]): any;
}
@@ -179,17 +119,3 @@ export interface TransitionInstruction {
enteringRequiresTransition?: boolean;
requiresTransition?: boolean;
}
export const STATE_NEW = 1;
export const STATE_INITIALIZED = 2;
export const STATE_ATTACHED = 3;
export const STATE_DESTROYED = 4;
export const INIT_ZINDEX = 100;
export const DIRECTION_BACK = 'back';
export const DIRECTION_FORWARD = 'forward';
export const DIRECTION_SWITCH = 'switch';
export const NAV = 'nav';
export const TABS = 'tabs';

View File

@@ -1,17 +1,13 @@
import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core';
import {
DIRECTION_BACK,
DIRECTION_FORWARD,
INIT_ZINDEX,
NavDirection,
NavOptions,
NavParams,
NavResult,
STATE_ATTACHED,
STATE_DESTROYED,
STATE_INITIALIZED,
STATE_NEW,
TransitionDoneFn,
TransitionInstruction,
ViewState,
convertToViews,
isPresent,
setZIndex
@@ -19,6 +15,7 @@ import {
import { ViewController, isViewController } from './view-controller';
import { AnimationOptions, Config, DomController, GestureDetail, NavOutlet } from '../..';
import { RouteID, RouteWrite } from '../router/utils/interfaces';
import { assert } from '../../utils/helpers';
import { TransitionController } from './transition-controller';
@@ -26,7 +23,6 @@ import { Transition } from './transition';
import iosTransitionAnimation from './animations/ios.transition';
import mdTransitionAnimation from './animations/md.transition';
import { RouteID, RouteWrite } from '../router/utils/interfaces';
const TrnsCtrl = new TransitionController();
@@ -208,6 +204,7 @@ export class NavControllerBase implements NavOutlet {
if (active && active.component === id) {
return Promise.resolve({changed: false});
}
const viewController = this._views.find(v => v.component === id) || id;
let resolve: (result: RouteWrite) => void;
const promise = new Promise<RouteWrite>((r) => resolve = r);
@@ -215,7 +212,7 @@ export class NavControllerBase implements NavOutlet {
const commonOpts: NavOptions = {
viewIsReady: () => {
let markVisible;
const p = new Promise((r) => markVisible = r);
const p = new Promise(r => markVisible = r);
resolve({
changed: true,
markVisible
@@ -225,17 +222,15 @@ export class NavControllerBase implements NavOutlet {
};
if (direction === 1) {
this.push(id, params, commonOpts);
this.push(viewController, params, commonOpts);
} else if (direction === -1) {
this.canGoBack()
? this.pop(commonOpts)
: this.setRoot(id, params, {
...commonOpts,
direction: DIRECTION_BACK,
animate: true
});
this.setRoot(id, params, {
...commonOpts,
direction: NavDirection.back,
animate: true
});
} else {
this.setRoot(id, params, commonOpts);
this.setRoot(viewController, params, commonOpts);
}
return promise;
}
@@ -365,7 +360,7 @@ export class NavControllerBase implements NavOutlet {
// let's see if there's another to kick off
this._nextTrns();
const router = document.querySelector('ion-router');
const isPop = result.direction === DIRECTION_BACK;
const isPop = result.direction === NavDirection.back;
if (router) {
router.navChanged(isPop);
}
@@ -441,7 +436,7 @@ export class NavControllerBase implements NavOutlet {
// Needs transition?
ti.requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
if (enteringView && enteringView._state === STATE_NEW) {
if (enteringView && enteringView._state === ViewState.New) {
this._viewInit(enteringView);
}
})
@@ -522,7 +517,7 @@ export class NavControllerBase implements NavOutlet {
if (nav && nav !== this) {
throw new Error('inserted view was already inserted');
}
if (view._state === STATE_DESTROYED) {
if (view._state === ViewState.Destroyed) {
throw new Error('inserted view was already destroyed');
}
}
@@ -575,7 +570,7 @@ export class NavControllerBase implements NavOutlet {
}
}
// default the direction to "back"
opts.direction = opts.direction || DIRECTION_BACK;
opts.direction = opts.direction || NavDirection.back;
}
const finalBalance = this._views.length + (insertViews ? insertViews.length : 0) - (removeCount ? removeCount : 0);
@@ -603,7 +598,7 @@ export class NavControllerBase implements NavOutlet {
if (ti.enteringRequiresTransition) {
// default to forward if not already set
opts.direction = opts.direction || DIRECTION_FORWARD;
opts.direction = opts.direction || NavDirection.forward;
}
}
@@ -640,15 +635,14 @@ export class NavControllerBase implements NavOutlet {
*/
private _viewInit(enteringView: ViewController) {
assert(enteringView, 'enteringView must be non null');
assert(enteringView._state === STATE_NEW, 'enteringView state must be NEW');
assert(enteringView._state === ViewState.New, 'enteringView state must be NEW');
enteringView._state = STATE_INITIALIZED;
enteringView._state = ViewState.Initialized;
enteringView.init();
enteringView._preLoad();
}
private _viewAttachToDOM(view: ViewController) {
assert(view._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
assert(view._state === ViewState.Initialized, 'view state must be INITIALIZED');
// fire willLoad before change detection runs
view._willLoad();
@@ -657,7 +651,7 @@ export class NavControllerBase implements NavOutlet {
// ******** DOM WRITE ****************
this.el.appendChild(view.element);
view._state = STATE_ATTACHED;
view._state = ViewState.Attached;
// successfully finished loading the entering view
// fire off the "didLoad" lifecycle events
@@ -726,7 +720,7 @@ export class NavControllerBase implements NavOutlet {
.then(() => this._transitionInit(transition, enteringView, leavingView, opts))
.then(() => this._transitionStart(transition, enteringView, leavingView, opts));
if (enteringView && (enteringView._state === STATE_INITIALIZED)) {
if (enteringView && (enteringView._state === ViewState.Initialized)) {
// render the entering component in the DOM
// this would also render new child navs/views
// which may have their very own async canEnter/Leave tests
@@ -894,7 +888,7 @@ export class NavControllerBase implements NavOutlet {
}
private _removeView(view: ViewController) {
assert(view._state === STATE_ATTACHED || view._state === STATE_DESTROYED, 'view state should be loaded or destroyed');
assert(view._state === ViewState.Attached || view._state === ViewState.Destroyed, 'view state should be loaded or destroyed');
const views = this._views;
const index = views.indexOf(view);
@@ -988,7 +982,7 @@ export class NavControllerBase implements NavOutlet {
// default the direction to "back";
const opts: NavOptions = {
direction: DIRECTION_BACK,
direction: NavDirection.back,
progressAnimation: true
};

View File

@@ -2,13 +2,10 @@ import { isPresent } from './nav-util';
import { Transition } from './transition';
import { NavControllerBase } from './nav';
export class TransitionController {
private _ids = 0;
private _trns = new Map<number, Transition>();
// constructor(public plt: Platform, private _config: Config) {}
getRootTrnsId(nav: NavControllerBase): number {
nav = nav.parent;
while (nav) {

View File

@@ -1,5 +1,5 @@
import { NavOptions, STATE_ATTACHED, STATE_DESTROYED, STATE_INITIALIZED, STATE_NEW } from './nav-util';
import { NavOptions, ViewState } from './nav-util';
import { NavControllerBase } from './nav';
import { assert } from '../../utils/helpers';
@@ -29,7 +29,7 @@ export class ViewController {
_nav: NavControllerBase;
_zIndex: number;
_state: number = STATE_NEW;
_state: ViewState = ViewState.New;
/** @hidden */
id: string;
@@ -162,10 +162,6 @@ export class ViewController {
}
}
_preLoad() {
assert(this._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
this._lifecycle('PreLoad');
}
/**
* @hidden
@@ -173,7 +169,7 @@ export class ViewController {
* This event is fired before the component and his children have been initialized.
*/
_willLoad() {
assert(this._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
assert(this._state === ViewState.Initialized, 'view state must be INITIALIZED');
this._lifecycle('WillLoad');
}
@@ -186,7 +182,7 @@ export class ViewController {
* recommended method to use when a view becomes active.
*/
_didLoad() {
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
this._lifecycle('DidLoad');
}
@@ -195,7 +191,7 @@ export class ViewController {
* The view is about to enter and become the active view.
*/
_willEnter() {
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
if (this._detached) {
// ensure this has been re-attached to the change detector
@@ -214,10 +210,8 @@ export class ViewController {
* will fire, whether it was the first load or loaded from the cache.
*/
_didEnter() {
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
// this._nb && this._nb.didEnter();
// this.didEnter.emit(null);
this._lifecycle('DidEnter');
}
@@ -226,7 +220,6 @@ export class ViewController {
* The view is about to leave and no longer be the active view.
*/
_willLeave(_willUnload: boolean) {
// this.willLeave.emit(null);
this._lifecycle('WillLeave');
}
@@ -236,7 +229,6 @@ export class ViewController {
* will fire, whether it is cached or unloaded.
*/
_didLeave() {
// this.didLeave.emit(null);
this._lifecycle('DidLeave');
// when this is not the active page
@@ -252,7 +244,6 @@ export class ViewController {
* @hidden
*/
_willUnload() {
// this.willUnload.emit(null);
this._lifecycle('WillUnload');
}
@@ -261,18 +252,15 @@ export class ViewController {
* DOM WRITE
*/
_destroy() {
assert(this._state !== STATE_DESTROYED, 'view state must be ATTACHED');
assert(this._state !== ViewState.Destroyed, 'view state must be ATTACHED');
const element = this.element;
if (element) {
// completely destroy this component. boom.
// TODO
// this._cmp.destroy();
element.remove();
}
this._nav = this._cntDir = this._leavingOpts = null;
this._state = STATE_DESTROYED;
this._state = ViewState.Destroyed;
}
/**
@@ -313,7 +301,6 @@ export class ViewController {
});
this.element.dispatchEvent(event);
}
}
export function isViewController(viewCtrl: any): viewCtrl is ViewController {