diff --git a/core/src/components/animation-controller/animation-interface.tsx b/core/src/components/animation-controller/animation-interface.tsx index 5f1b3b8f5a..aa2de19145 100644 --- a/core/src/components/animation-controller/animation-interface.tsx +++ b/core/src/components/animation-controller/animation-interface.tsx @@ -44,7 +44,7 @@ export interface Animation { export interface AnimationBuilder { - (Animation: Animation, baseEl?: HTMLElement, opts?: any): Promise; + (Animation: Animation, baseEl: HTMLElement, opts?: any): Promise; } export interface PlayOptions { diff --git a/core/src/components/nav/nav-util.ts b/core/src/components/nav/nav-util.ts index b434694471..7579ff9c8d 100644 --- a/core/src/components/nav/nav-util.ts +++ b/core/src/components/nav/nav-util.ts @@ -1,7 +1,7 @@ import { ViewController, isViewController } from './view-controller'; import { Animation, FrameworkDelegate } from '../..'; -export function convertToView(page: any, params: any): ViewController { +export function convertToView(page: any, params: any): ViewController|null { if (!page) { return null; } @@ -20,8 +20,7 @@ export function convertToViews(pages: any[]): ViewController[] { return convertToView(page.page, page.params); } return convertToView(page, undefined); - }) - .filter(v => v !== null); + }).filter(v => v !== null) as ViewController[]; } export function isPresent(val: any): val is any { @@ -80,7 +79,7 @@ export interface TransitionDoneFn { } export interface TransitionInstruction { - opts: NavOptions; + opts: NavOptions|undefined; insertStart?: number; insertViews?: any[]; removeView?: ViewController; diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index 29b935dd5e..3ad22535c4 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -150,7 +150,7 @@ export class NavControllerBase implements NavOutlet { popAll(): Promise { const promises: Promise[] = []; for (let i = this._views.length - 1; i >= 0; i--) { - promises.push(this.pop(null)); + promises.push(this.pop(undefined)); } return Promise.all(promises); } @@ -235,7 +235,7 @@ export class NavControllerBase implements NavOutlet { } @Method() - getRouteId(): RouteID|null { + getRouteId(): RouteID|undefined { const active = this.getActive(); if (active) { return { @@ -243,16 +243,16 @@ export class NavControllerBase implements NavOutlet { params: active.data }; } - return null; + return undefined; } @Method() - getContainerEl(): HTMLElement { + getContainerEl(): HTMLElement|undefined { const active = this.getActive(); if (active) { return active.element; } - return null; + return undefined; } @Method() @@ -276,10 +276,10 @@ export class NavControllerBase implements NavOutlet { } @Method() - getPrevious(view = this.getActive()): ViewController { + getPrevious(view = this.getActive()): ViewController|undefined { const views = this._views; const index = views.indexOf(view); - return (index > 0) ? views[index - 1] : null; + return (index > 0) ? views[index - 1] : undefined; } @Method() @@ -291,7 +291,7 @@ export class NavControllerBase implements NavOutlet { * Return a view controller */ @Method() - getViewById(id: string): ViewController { + getViewById(id: string): ViewController|undefined { return this._views.find(vc => vc.id === id); } @@ -313,7 +313,7 @@ export class NavControllerBase implements NavOutlet { // 7. _transitionStart(): called once the transition actually starts, it initializes the Animation underneath. // 8. _transitionFinish(): called once the transition finishes // 9. _cleanup(): syncs the navigation internal state with the DOM. For example it removes the pages from the DOM or hides/show them. - private _queueTrns(ti: TransitionInstruction, done: TransitionDoneFn): Promise { + private _queueTrns(ti: TransitionInstruction, done: TransitionDoneFn|undefined): Promise { const promise = new Promise((resolve, reject) => { ti.resolve = resolve; ti.reject = reject; @@ -349,7 +349,7 @@ export class NavControllerBase implements NavOutlet { const isPop = result.direction === NavDirection.back; if (this.useRouter) { const router = document.querySelector('ion-router'); - router.navChanged(isPop); + router && router.navChanged(isPop); } this.ionNavChanged.emit({isPop}); @@ -438,7 +438,7 @@ export class NavControllerBase implements NavOutlet { private _prepareTI(ti: TransitionInstruction) { const viewsLength = this._views.length; - if (isPresent(ti.removeView)) { + if (ti.removeView != null) { assert(isPresent(ti.removeStart), 'removeView needs removeStart'); assert(isPresent(ti.removeCount), 'removeView needs removeCount'); @@ -448,7 +448,7 @@ export class NavControllerBase implements NavOutlet { } ti.removeStart += index; } - if (isPresent(ti.removeStart)) { + if (ti.removeStart != null) { if (ti.removeStart < 0) { ti.removeStart = (viewsLength - 1); } @@ -523,7 +523,7 @@ export class NavControllerBase implements NavOutlet { const insertViews = ti.insertViews; const removeStart = ti.removeStart; const removeCount = ti.removeCount; - let destroyQueue: ViewController[]; + let destroyQueue: ViewController[] = undefined; // there are views to remove if (isPresent(removeStart)) { @@ -597,7 +597,7 @@ export class NavControllerBase implements NavOutlet { } } - private _transition(enteringView: ViewController, leavingView: ViewController, ti: TransitionInstruction): Promise { + private async _transition(enteringView: ViewController, leavingView: ViewController, ti: TransitionInstruction): Promise { if (!ti.requiresTransition) { // transition is not required, so we are already done! // they're inserting/removing the views somewhere in the middle or @@ -645,12 +645,11 @@ export class NavControllerBase implements NavOutlet { enteringEl, leavingEl }; - return transition(animationOpts) - .then(trns => this._transitionFinish(trns, enteringView, leavingView, ti.opts)); + const trns = await transition(animationOpts); + return this._transitionFinish(trns, enteringView, leavingView, ti.opts); } - private _transitionFinish(transition: Animation, enteringView: ViewController, leavingView: ViewController, opts: NavOptions): NavResult { - + private _transitionFinish(transition: Animation|void, enteringView: ViewController, leavingView: ViewController, opts: NavOptions): NavResult { const hasCompleted = transition ? transition.hasCompleted : true; if (hasCompleted) { @@ -777,7 +776,7 @@ export class NavControllerBase implements NavOutlet { removeStart: -1, removeCount: 1, opts: opts, - }, null); + }, undefined); } private swipeBackProgress(detail: GestureDetail) { diff --git a/core/src/components/nav/transition.ts b/core/src/components/nav/transition.ts index 1a0c57a74e..042dff75cb 100644 --- a/core/src/components/nav/transition.ts +++ b/core/src/components/nav/transition.ts @@ -1,7 +1,7 @@ import { NavDirection } from './nav-util'; import { Animation, AnimationBuilder } from '../..'; -export function transition(opts: AnimationOptions): Promise { +export async function transition(opts: AnimationOptions): Promise { const enteringEl = opts.enteringEl; const leavingEl = opts.leavingEl; @@ -15,51 +15,49 @@ export function transition(opts: AnimationOptions): Promise } // transition path - return waitDeepReady(opts) - .then(() => fireWillEvents(enteringEl, leavingEl)) - .then(() => createTransition(opts)) - .then((transition) => playTransition(transition, opts)) - .then((transition) => { - if (transition.hasCompleted) { - fireDidEvents(enteringEl, leavingEl); - } - return transition; - }); -} - -function notifyViewReady(viewIsReady: undefined | (() => Promise)) { - if (viewIsReady) { - return viewIsReady(); + await waitDeepReady(opts); + const transition = await createTransition(opts); + fireWillEvents(enteringEl, leavingEl); + await playTransition(transition, opts); + if (transition.hasCompleted) { + fireDidEvents(enteringEl, leavingEl); } - return Promise.resolve(); + return transition; } -function noAnimation(opts: AnimationOptions) { +async function notifyViewReady(viewIsReady: undefined | (() => Promise)) { + if (viewIsReady) { + await viewIsReady(); + } +} + +async function noAnimation(opts: AnimationOptions) { const enteringEl = opts.enteringEl; const leavingEl = opts.leavingEl; enteringEl && enteringEl.classList.remove('hide-page'); leavingEl && leavingEl.classList.remove('hide-page'); - return waitShallowReady(opts).then(() => { - fireWillEvents(enteringEl, leavingEl); - fireDidEvents(enteringEl, leavingEl); - return undefined; - }); + await waitShallowReady(opts); + + fireWillEvents(enteringEl, leavingEl); + fireDidEvents(enteringEl, leavingEl); } -function waitDeepReady(opts: AnimationOptions) { - return Promise.all([ +async function waitDeepReady(opts: AnimationOptions) { + await Promise.all([ deepReady(opts.enteringEl), deepReady(opts.leavingEl) - ]).then(() => notifyViewReady(opts.viewIsReady)); + ]); + await notifyViewReady(opts.viewIsReady); } -function waitShallowReady(opts: AnimationOptions) { - return Promise.all([ +async function waitShallowReady(opts: AnimationOptions) { + await Promise.all([ shallowReady(opts.enteringEl), shallowReady(opts.leavingEl) - ]).then(() => notifyViewReady(opts.viewIsReady)); + ]); + await notifyViewReady(opts.viewIsReady); } function showPages(enteringEl: HTMLElement, leavingEl: HTMLElement) { @@ -140,14 +138,14 @@ export function lifecycle(el: HTMLElement, lifecycle: ViewLifecycle) { } } -function shallowReady(el: HTMLElement): Promise { +function shallowReady(el: Element): Promise { if (el && (el as any).componentOnReady) { return (el as any).componentOnReady(); } return Promise.resolve(); } -function deepReady(el: HTMLElement): Promise { +function deepReady(el: Element): Promise { if (!el) { return Promise.resolve(); } @@ -158,7 +156,7 @@ function deepReady(el: HTMLElement): Promise { } } -export enum ViewLifecycle { +export const enum ViewLifecycle { WillEnter = 'ionViewWillEnter', DidEnter = 'ionViewDidEnter', WillLeave = 'ionViewWillLeave', diff --git a/core/src/components/router/utils/dom.ts b/core/src/components/router/utils/dom.ts index d5174a6213..efd8a4e4ba 100644 --- a/core/src/components/router/utils/dom.ts +++ b/core/src/components/router/utils/dom.ts @@ -21,19 +21,19 @@ export function writeNavState(root: HTMLElement, chain: RouteChain|null, index: ? writeNavState(nextEl, chain, index + 1, direction) : Promise.resolve(direction === 0); - if (result.markVisible) { - return promise.then((c) => { + return promise.then((c) => { + if (result.markVisible) { result.markVisible(); - return c; - }); - } - return promise; + } + return c; + }); }); } -export function readNavState(node: HTMLElement) { +export function readNavState(root: HTMLElement) { const ids: RouteID[] = []; let pivot: NavOutlet|null; + let node: HTMLElement|undefined = root; while (true) { pivot = searchNavNode(node); if (pivot) { @@ -53,7 +53,10 @@ export function readNavState(node: HTMLElement) { const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs'; -function searchNavNode(root: HTMLElement): NavOutletElement { +function searchNavNode(root: HTMLElement|undefined): NavOutletElement|null { + if (!root) { + return null; + } if (root.matches(QUERY)) { return root as NavOutletElement; } diff --git a/core/src/components/router/utils/interfaces.ts b/core/src/components/router/utils/interfaces.ts index 8df8eaaf66..28594ccece 100644 --- a/core/src/components/router/utils/interfaces.ts +++ b/core/src/components/router/utils/interfaces.ts @@ -1,9 +1,9 @@ export interface NavOutlet { setRouteId(id: string, data: any, direction: number): Promise; - getRouteId(): RouteID|null; + getRouteId(): RouteID|undefined; - getContainerEl(): HTMLElement | null; + getContainerEl(): HTMLElement | undefined; } export interface RouterEventDetail { diff --git a/core/src/components/tabs/tabs.tsx b/core/src/components/tabs/tabs.tsx index 47f93f2e2b..c251557ead 100644 --- a/core/src/components/tabs/tabs.tsx +++ b/core/src/components/tabs/tabs.tsx @@ -139,13 +139,13 @@ export class Tabs implements NavOutlet { } @Method() - getRouteId(): RouteID|null { + getRouteId(): RouteID|undefined { const id = this.selectedTab && this.selectedTab.getTabId(); - return id ? {id} : null; + return id ? {id} : undefined; } @Method() - getContainerEl(): HTMLElement { + getContainerEl(): HTMLElement|undefined { return this.selectedTab; } diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index a8c3b7138e..3b238cede5 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -157,7 +157,7 @@ export function attachComponent(delegate: FrameworkDelegate, container: Element, export function eventMethod(element: HTMLElement, eventName: string, callback?: (detail: T) => void): Promise { let resolve: Function; const promise = new Promise(r => resolve = r); - onceEvent(element, eventName, (event) => { + onceEvent(element, eventName, (event: any) => { const detail = event.detail; callback && callback(detail); resolve(detail); @@ -165,8 +165,8 @@ export function eventMethod(element: HTMLElement, eventName: string, callback return promise; } -export function onceEvent(element: HTMLElement, eventName: string, callback: (ev: CustomEvent) => void) { - const handler = (ev: CustomEvent) => { +export function onceEvent(element: HTMLElement, eventName: string, callback: (ev: Event) => void) { + const handler = (ev: Event) => { element.removeEventListener(eventName, handler); callback(ev); }; @@ -178,7 +178,7 @@ function closeKeyboard() { activeElement && activeElement.blur && activeElement.blur(); } -export function isCancel(role: string): boolean { +export function isCancel(role: string|undefined): boolean { return role === 'cancel' || role === BACKDROP; } diff --git a/core/stencil.config.js b/core/stencil.config.js index 8e12c862fd..763398a1c0 100644 --- a/core/stencil.config.js +++ b/core/stencil.config.js @@ -33,7 +33,7 @@ exports.config = { { components: ['ion-popover', 'ion-popover-controller'] }, { components: ['ion-radio', 'ion-radio-group'] }, { components: ['ion-reorder', 'ion-reorder-group'] }, - { components: ['ion-route', 'ion-router'] }, + { components: ['ion-router', 'ion-route', 'ion-route-redirect'] }, { components: ['ion-searchbar'] }, { components: ['ion-segment', 'ion-segment-button'] }, { components: ['ion-select', 'ion-select-option', 'ion-select-popover'] }, diff --git a/core/tsconfig.json b/core/tsconfig.json index 377d6917ac..9457daeb8d 100644 --- a/core/tsconfig.json +++ b/core/tsconfig.json @@ -22,7 +22,7 @@ "outDir": ".tmp", "pretty": true, "removeComments": false, - "target": "es2015" + "target": "es2017" }, "include": [ "src/**/*.ts",