diff --git a/packages/core/src/components/nav-controller/nav-controller.tsx b/packages/core/src/components/nav-controller/nav-controller.tsx index 5b94c95649..7d4c9588ac 100644 --- a/packages/core/src/components/nav-controller/nav-controller.tsx +++ b/packages/core/src/components/nav-controller/nav-controller.tsx @@ -1,4 +1,5 @@ import { Component, Element, Method, Prop } from '@stencil/core'; +import { Animation, AnimationController } from '../..'; import { ComponentDataPair, FrameworkDelegate, Nav, NavController, NavOptions, ViewController } from '../../navigation/nav-interfaces'; import { isReady } from '../../utils/helpers'; @@ -25,78 +26,79 @@ export class NavControllerImpl implements NavController { @Element() element: HTMLElement; @Prop() delegate: FrameworkDelegate; + @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; + constructor() { } @Method() push(nav: Nav, component: any, data?: any, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return pushImpl(nav, delegate, component, data, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return pushImpl(nav, delegate, animation, component, data, opts); }); } @Method() pop(nav: Nav, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return popImpl(nav, delegate, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return popImpl(nav, delegate, animation, opts); }); - } @Method() setRoot(nav: Nav, component: any, data?: any, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return setRootImpl(nav, delegate, component, data, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return setRootImpl(nav, delegate, animation, component, data, opts); }); } @Method() insert(nav: Nav, insertIndex: number, page: any, params?: any, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return insertImpl(nav, delegate, insertIndex, page, params, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return insertImpl(nav, delegate, animation, insertIndex, page, params, opts); }); } @Method() insertPages(nav: Nav, insertIndex: number, insertPages: any[], opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return insertPagesImpl(nav, delegate, insertIndex, insertPages, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return insertPagesImpl(nav, delegate, animation, insertIndex, insertPages, opts); }); } @Method() popToRoot(nav: Nav, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return popToRootImpl(nav, delegate, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return popToRootImpl(nav, delegate, animation, opts); }); } @Method() popTo(nav: Nav, indexOrViewCtrl: any, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return popToImpl(nav, delegate, indexOrViewCtrl, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return popToImpl(nav, delegate, animation, indexOrViewCtrl, opts); }); } @Method() remove(nav: Nav, startIndex: number, removeCount?: number, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return removeImpl(nav, delegate, startIndex, removeCount, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return removeImpl(nav, delegate, animation, startIndex, removeCount, opts); }); } @Method() removeView(nav: Nav, viewController: ViewController, opts?: NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return removeViewImpl(nav, delegate, viewController, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return removeViewImpl(nav, delegate, animation, viewController, opts); }); } @Method() setPages(nav: Nav, componentDataPairs: ComponentDataPair[], opts? : NavOptions): Promise { - return getDelegate(this).then((delegate) => { - return setPagesImpl(nav, delegate, componentDataPairs, opts); + return hydrateDelegateAndAnimation(this).then(([delegate, animation]) => { + return setPagesImpl(nav, delegate, animation, componentDataPairs, opts); }); } @@ -105,7 +107,11 @@ export class NavControllerImpl implements NavController { } } -export function getDelegate(navController: NavController): Promise { +export function hydrateDelegateAndAnimation(navController: NavController): Promise { + return Promise.all([hydrateDelegate(navController), hydrateAnimationController(navController.animationCtrl)]); +} + +export function hydrateDelegate(navController: NavController): Promise { if (navController.delegate) { return Promise.resolve(navController.delegate); } @@ -115,5 +121,9 @@ export function getDelegate(navController: NavController): Promise { defaultDelegate = element as any as FrameworkDelegate; return defaultDelegate; - }) + }); +} + +export function hydrateAnimationController(animationController: AnimationController): Promise { + return animationController.create(); } \ No newline at end of file diff --git a/packages/core/src/components/nav/nav.tsx b/packages/core/src/components/nav/nav.tsx index 5c0dd1e854..d000680ad3 100644 --- a/packages/core/src/components/nav/nav.tsx +++ b/packages/core/src/components/nav/nav.tsx @@ -1,5 +1,5 @@ import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core'; -import { AnimationController, Config } from '../..'; +import { Config } from '../..'; import { ComponentDataPair, FrameworkDelegate, Nav, NavController, NavOptions, ViewController } from '../../navigation/nav-interfaces'; import { getActiveImpl, getFirstView, getPreviousImpl, getViews, init } from '../../navigation/nav-utils'; @@ -25,9 +25,9 @@ export class IonNav implements Nav { childNavs?: Nav[]; navController?: NavController; + @Prop() mode: string; @Prop() root: any; @Prop() delegate: FrameworkDelegate; - @Prop({ connect: 'ion-animation-controller' }) animationCtrl: AnimationController; @Prop({ context: 'config' }) config: Config; constructor() { @@ -119,8 +119,8 @@ export class IonNav implements Nav { } @Listen('navInit') - navInitialized(event: any) { - console.log('got the event: ', event); + navInitialized(event: CustomEvent) { + navInitializedImpl(this, event); } @@ -203,4 +203,14 @@ export function getNavController(nav: Nav): Promise { } nav.navController = document.querySelector('ion-nav-controller') as any as NavController; return isReady(nav.navController as any as HTMLElement); +} + +export function navInitializedImpl(nav: Nav, event: CustomEvent) { + if (nav.element !== event.target) { + console.log('nav.id is parent of: ', (event as any).detail.id); + // set the parent on the child nav that dispatched the event + (event.detail as Nav).parent = nav; + // kill the event so it doesn't propagate further + event.stopPropagation(); + } } \ No newline at end of file diff --git a/packages/core/src/navigation/nav-controller-functions.ts b/packages/core/src/navigation/nav-controller-functions.ts index 40b267b85a..cbb178aa88 100644 --- a/packages/core/src/navigation/nav-controller-functions.ts +++ b/packages/core/src/navigation/nav-controller-functions.ts @@ -39,69 +39,75 @@ const queueMap = new Map(); // public api -export function push(nav: Nav, delegate: FrameworkDelegate, component: any, data?: any, opts?: NavOptions, done? : () => void): Promise { +export function push(nav: Nav, delegate: FrameworkDelegate, animation: Animation, component: any, data?: any, opts?: NavOptions, done? : () => void): Promise { return queueTransaction({ insertStart: -1, insertViews: [{page: component, params: data}], opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function insert(nav: Nav, delegate: FrameworkDelegate, insertIndex: number, page: any, params?: any, opts?: NavOptions, done?: () => void): Promise { +export function insert(nav: Nav, delegate: FrameworkDelegate, animation: Animation, insertIndex: number, page: any, params?: any, opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ insertStart: insertIndex, insertViews: [{ page: page, params: params }], opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function insertPages(nav: Nav, delegate: FrameworkDelegate, insertIndex: number, insertPages: any[], opts?: NavOptions, done?: () => void): Promise { +export function insertPages(nav: Nav, delegate: FrameworkDelegate, animation: Animation, insertIndex: number, insertPages: any[], opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ insertStart: insertIndex, insertViews: insertPages, opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function pop(nav: Nav, delegate: FrameworkDelegate, opts?: NavOptions, done?: () => void): Promise { +export function pop(nav: Nav, delegate: FrameworkDelegate, animation: Animation, opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ removeStart: -1, removeCount: 1, opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function popToRoot(nav: Nav, delegate: FrameworkDelegate, opts?: NavOptions, done?: () => void): Promise { +export function popToRoot(nav: Nav, delegate: FrameworkDelegate, animation: Animation, opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ removeStart: 1, removeCount: -1, opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function popTo(nav: Nav, delegate: FrameworkDelegate, indexOrViewCtrl: any, opts?: NavOptions, done?: () => void): Promise { +export function popTo(nav: Nav, delegate: FrameworkDelegate, animation: Animation, indexOrViewCtrl: any, opts?: NavOptions, done?: () => void): Promise { const config: TransitionInstruction = { removeStart: -1, removeCount: -1, opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }; if (isViewController(indexOrViewCtrl)) { config.removeView = indexOrViewCtrl; @@ -112,18 +118,19 @@ export function popTo(nav: Nav, delegate: FrameworkDelegate, indexOrViewCtrl: an return queueTransaction(config, done); } -export function remove(nav: Nav, delegate: FrameworkDelegate, startIndex: number, removeCount: number = 1, opts?: NavOptions, done?: () => void): Promise { +export function remove(nav: Nav, delegate: FrameworkDelegate, animation: Animation, startIndex: number, removeCount: number = 1, opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ removeStart: startIndex, removeCount: removeCount, opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function removeView(nav: Nav, delegate: FrameworkDelegate, viewController: ViewController, opts?: NavOptions, done?: () => void): Promise { +export function removeView(nav: Nav, delegate: FrameworkDelegate, animation: Animation, viewController: ViewController, opts?: NavOptions, done?: () => void): Promise { return queueTransaction({ removeView: viewController, removeStart: 0, @@ -131,15 +138,16 @@ export function removeView(nav: Nav, delegate: FrameworkDelegate, viewController opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } -export function setRoot(nav: Nav, delegate: FrameworkDelegate, page: any, params?: any, opts?: NavOptions, done?: () => void): Promise { - return setPages(nav, delegate, [{ page: page, params: params }], opts, done); +export function setRoot(nav: Nav, delegate: FrameworkDelegate, animation: Animation, page: any, params?: any, opts?: NavOptions, done?: () => void): Promise { + return setPages(nav, delegate, animation, [{ page: page, params: params }], opts, done); } -export function setPages(nav: Nav, delegate: FrameworkDelegate, componentDataPars: ComponentDataPair[], opts? : NavOptions, done?: () => void): Promise { +export function setPages(nav: Nav, delegate: FrameworkDelegate, animation: Animation, componentDataPars: ComponentDataPair[], opts? : NavOptions, done?: () => void): Promise { if (!isDef(opts)) { opts = {}; } @@ -154,7 +162,8 @@ export function setPages(nav: Nav, delegate: FrameworkDelegate, componentDataPar opts: opts, nav: nav, delegate: delegate, - id: nav.id + id: nav.id, + animation: animation }, done); } @@ -303,26 +312,22 @@ export function loadViewAndTransition(nav: Nav, enteringView: ViewController, le ev: ti.opts.event, }; - return nav.animationCtrl.create().then((animation: Animation) => { - const emptyTransition = transitionFactory(animation); - console.log('nav.config: ', nav.config); - console.log('mode: ', nav.config.get('mode')); - transition = getHydratedTransition(animationOpts.animation, nav.config, nav.transitionId, emptyTransition, enteringView, leavingView, animationOpts, buildMdTransition); + const emptyTransition = transitionFactory(ti.animation); + transition = getHydratedTransition(animationOpts.animation, nav.config, nav.transitionId, emptyTransition, enteringView, leavingView, animationOpts, buildMdTransition); - if (nav.swipeToGoBackTransition) { - nav.swipeToGoBackTransition.destroy(); - nav.swipeToGoBackTransition = null; - } + if (nav.swipeToGoBackTransition) { + nav.swipeToGoBackTransition.destroy(); + nav.swipeToGoBackTransition = null; + } - // it's a swipe to go back transition - if (transition.isRoot() && ti.opts.progressAnimation) { - nav.swipeToGoBackTransition = transition; - } + // it's a swipe to go back transition + if (transition.isRoot() && ti.opts.progressAnimation) { + nav.swipeToGoBackTransition = transition; + } - transition.start(); - }).then(() => { - return executeAsyncTransition(nav, transition, enteringView, leavingView, ti.delegate, ti.opts, ti.nav.config.getBoolean('animate')); - }); + transition.start(); + + return executeAsyncTransition(nav, transition, enteringView, leavingView, ti.delegate, ti.opts, ti.nav.config.getBoolean('animate')); } // TODO - transition type diff --git a/packages/core/src/navigation/nav-interfaces.d.ts b/packages/core/src/navigation/nav-interfaces.d.ts index cf445e29ec..1cef2bd32c 100644 --- a/packages/core/src/navigation/nav-interfaces.d.ts +++ b/packages/core/src/navigation/nav-interfaces.d.ts @@ -29,7 +29,7 @@ export interface Nav { root?: any; navInit?: EventEmitter; config?: Config; - animationCtrl?: AnimationController; + mode?: string; // public methods getActive(): ViewController; @@ -58,7 +58,9 @@ export interface NavController { remove(nav: Nav, startIndex: number, removeCount: number, opts: NavOptions): Promise; removeView(nav: Nav, viewController: ViewController, opts?: NavOptions): Promise; setPages(nav: Nav, componentDataPairs: ComponentDataPair[], opts? : NavOptions): Promise; + delegate?: FrameworkDelegate; + animationCtrl?: AnimationController; } export interface ViewController { @@ -126,6 +128,7 @@ export interface TransitionInstruction { id?: number; nav?: Nav; delegate?: FrameworkDelegate; + animation?: Animation; } export interface NavResult {