diff --git a/packages/core/src/components/nav/nav-util.ts b/packages/core/src/components/nav/nav-util.ts index 538daa9ded..cb491d3ab6 100644 --- a/packages/core/src/components/nav/nav-util.ts +++ b/packages/core/src/components/nav/nav-util.ts @@ -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 = 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; } -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'; diff --git a/packages/core/src/components/nav/nav.tsx b/packages/core/src/components/nav/nav.tsx index 6e50c16645..7e36c4fc6b 100644 --- a/packages/core/src/components/nav/nav.tsx +++ b/packages/core/src/components/nav/nav.tsx @@ -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((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 }; diff --git a/packages/core/src/components/nav/transition-controller.ts b/packages/core/src/components/nav/transition-controller.ts index e7573bd71e..480aea5897 100644 --- a/packages/core/src/components/nav/transition-controller.ts +++ b/packages/core/src/components/nav/transition-controller.ts @@ -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(); - // constructor(public plt: Platform, private _config: Config) {} - getRootTrnsId(nav: NavControllerBase): number { nav = nav.parent; while (nav) { diff --git a/packages/core/src/components/nav/view-controller.ts b/packages/core/src/components/nav/view-controller.ts index 174ca9ea33..e6e3be5c02 100644 --- a/packages/core/src/components/nav/view-controller.ts +++ b/packages/core/src/components/nav/view-controller.ts @@ -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 {