diff --git a/core/package.json b/core/package.json index 508b1a527d..2457a7c3e3 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ "stylelint-order": "~1.0.0", "swiper": "4.4.1", "tslint": "^5.10.0", - "tslint-ionic-rules": "0.0.20", + "tslint-ionic-rules": "0.0.21", "tslint-react": "^3.6.0", "typescript": "^2.9.2" }, diff --git a/core/src/components.d.ts b/core/src/components.d.ts index b2370e43fb..6fcce7bf8e 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -2795,7 +2795,7 @@ export namespace Components { * Set the root for the current navigation stack. */ 'setRoot': (component: T, componentProps?: ComponentProps | null | undefined, opts?: NavOptions | null | undefined, done?: TransitionDoneFn | undefined) => Promise; - 'setRouteId': (id: string, params: { [key: string]: any; } | undefined, direction: number) => Promise; + 'setRouteId': (id: string, params: { [key: string]: any; } | undefined, direction: RouterDirection) => Promise; /** * If the nav component should allow for swipe-to-go-back. */ @@ -3626,7 +3626,7 @@ export namespace Components { 'delegate'?: FrameworkDelegate; 'getRouteId': () => Promise; 'mode': Mode; - 'setRouteId': (id: string, params: { [key: string]: any; } | undefined, direction: number) => Promise; + 'setRouteId': (id: string, params: { [key: string]: any; } | undefined, direction: RouterDirection) => Promise; 'swipeHandler'?: SwipeGestureHandler; } interface IonRouterOutletAttributes extends StencilHTMLAttributes { @@ -3651,7 +3651,7 @@ export namespace Components { * Go back to previous page in the window.history. */ 'goBack': () => Promise; - 'navChanged': (intent: number) => Promise; + 'navChanged': (direction: RouterDirection) => Promise; 'printDebug': () => void; /** * Navigate to the specified URL. diff --git a/core/src/components/nav/constants.ts b/core/src/components/nav/constants.ts new file mode 100644 index 0000000000..dc9b0417ff --- /dev/null +++ b/core/src/components/nav/constants.ts @@ -0,0 +1,5 @@ +export const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter'; +export const LIFECYCLE_DID_ENTER = 'ionViewDidEnter'; +export const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave'; +export const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave'; +export const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload'; diff --git a/core/src/components/nav/nav-interface.ts b/core/src/components/nav/nav-interface.ts index ee649df197..66d4e2ab47 100644 --- a/core/src/components/nav/nav-interface.ts +++ b/core/src/components/nav/nav-interface.ts @@ -1,4 +1,6 @@ -import { Animation, AnimationBuilder, ComponentRef, FrameworkDelegate, Mode, ViewController } from '../../interface'; +import { Animation, AnimationBuilder, ComponentRef, FrameworkDelegate, Mode } from '../../interface'; + +import { ViewController } from './view-controller'; export type NavDirection = 'back' | 'forward'; @@ -62,3 +64,5 @@ export interface TransitionInstruction { leavingRequiresTransition?: boolean; enteringRequiresTransition?: boolean; } + +export { ViewController }; diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index d37213137d..92ba7f3ada 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -1,11 +1,11 @@ import { Build, Component, Element, Event, EventEmitter, Method, Prop, QueueApi, Watch } from '@stencil/core'; -import { ViewLifecycle } from '../..'; -import { Animation, AnimationBuilder, ComponentProps, Config, FrameworkDelegate, Gesture, Mode, NavComponent, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface'; +import { Animation, AnimationBuilder, ComponentProps, Config, FrameworkDelegate, Gesture, Mode, NavComponent, NavOptions, NavOutlet, NavResult, RouteID, RouteWrite, RouterDirection, TransitionDoneFn, TransitionInstruction, ViewController } from '../../interface'; import { assert } from '../../utils/helpers'; import { TransitionOptions, lifecycle, setPageHidden, transition } from '../../utils/transition'; -import { ViewState, convertToViews, matches } from './view-controller'; +import { LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_LEAVE, LIFECYCLE_WILL_UNLOAD } from './constants'; +import { VIEW_STATE_ATTACHED, VIEW_STATE_DESTROYED, VIEW_STATE_NEW, convertToViews, matches } from './view-controller'; @Component({ tag: 'ion-nav', @@ -124,7 +124,7 @@ export class Nav implements NavOutlet { componentDidUnload() { for (const view of this.views) { - lifecycle(view.element!, ViewLifecycle.WillUnload); + lifecycle(view.element!, LIFECYCLE_WILL_UNLOAD); view._destroy(); } @@ -324,7 +324,7 @@ export class Nav implements NavOutlet { setRouteId( id: string, params: ComponentProps | undefined, - direction: number + direction: RouterDirection ): Promise { const active = this.getActiveSync(); if (matches(active, id, params)) { @@ -354,7 +354,7 @@ export class Nav implements NavOutlet { } }; - if (direction === 0) { + if (direction === 'root') { finish = this.setRoot(id, params, commonOpts); } else { const viewController = this.views.find(v => matches(v, id, params)); @@ -364,9 +364,9 @@ export class Nav implements NavOutlet { ...commonOpts, direction: 'back' }); - } else if (direction === 1) { + } else if (direction === 'forward') { finish = this.push(id, params, commonOpts); - } else if (direction === -1) { + } else if (direction === 'back') { finish = this.setRoot(id, params, { ...commonOpts, direction: 'back', @@ -502,7 +502,7 @@ export class Nav implements NavOutlet { if (ti.opts!.updateURL !== false && this.useRouter) { const router = this.win.document.querySelector('ion-router'); if (router) { - const direction = result.direction === 'back' ? -1 : 1; + const direction = result.direction === 'back' ? 'back' : 'forward'; router.navChanged(direction); } } @@ -560,7 +560,7 @@ export class Nav implements NavOutlet { throw new Error('no views in the stack to be removed'); } - if (enteringView && enteringView.state === ViewState.New) { + if (enteringView && enteringView.state === VIEW_STATE_NEW) { await enteringView.init(this.el); } this.postViewInit(enteringView, leavingView, ti); @@ -645,7 +645,7 @@ export class Nav implements NavOutlet { if (nav && nav !== this) { throw new Error('inserted view was already inserted'); } - if (view.state === ViewState.Destroyed) { + if (view.state === VIEW_STATE_DESTROYED) { throw new Error('inserted view was already destroyed'); } } @@ -749,9 +749,9 @@ export class Nav implements NavOutlet { // let's make sure, callbacks are zoned if (destroyQueue && destroyQueue.length > 0) { for (const view of destroyQueue) { - lifecycle(view.element, ViewLifecycle.WillLeave); - lifecycle(view.element, ViewLifecycle.DidLeave); - lifecycle(view.element, ViewLifecycle.WillUnload); + lifecycle(view.element, LIFECYCLE_WILL_LEAVE); + lifecycle(view.element, LIFECYCLE_DID_LEAVE); + lifecycle(view.element, LIFECYCLE_WILL_UNLOAD); } // once all lifecycle events has been delivered, we can safely detroy the views @@ -837,7 +837,7 @@ export class Nav implements NavOutlet { private removeView(view: ViewController) { assert( - view.state === ViewState.Attached || view.state === ViewState.Destroyed, + view.state === VIEW_STATE_ATTACHED || view.state === VIEW_STATE_DESTROYED, 'view state should be loaded or destroyed' ); @@ -873,7 +873,7 @@ export class Nav implements NavOutlet { if (i > activeViewIndex) { // this view comes after the active view // let's unload it - lifecycle(element, ViewLifecycle.WillUnload); + lifecycle(element, LIFECYCLE_WILL_UNLOAD); this.destroyView(view); } else if (i < activeViewIndex) { // this view comes before the active view diff --git a/core/src/components/nav/test/nav-controller.spec.ts b/core/src/components/nav/test/nav-controller.spec.ts index 44983af950..fe604f0d87 100644 --- a/core/src/components/nav/test/nav-controller.spec.ts +++ b/core/src/components/nav/test/nav-controller.spec.ts @@ -952,7 +952,7 @@ describe('NavController', () => { ? win.document.createElement(enteringView.component) : enteringView.element = enteringView.component as HTMLElement; } - enteringView.state = ViewState.Attached; + enteringView.state = VIEW_STATE_ATTACHED; }; return navI; } diff --git a/core/src/components/nav/view-controller.ts b/core/src/components/nav/view-controller.ts index da06a1924a..99903f2335 100644 --- a/core/src/components/nav/view-controller.ts +++ b/core/src/components/nav/view-controller.ts @@ -2,15 +2,13 @@ import { ComponentProps, FrameworkDelegate } from '../../interface'; import { attachComponent } from '../../utils/framework-delegate'; import { assert } from '../../utils/helpers'; -export const enum ViewState { - New = 1, - Attached, - Destroyed -} +export const VIEW_STATE_NEW = 1; +export const VIEW_STATE_ATTACHED = 2; +export const VIEW_STATE_DESTROYED = 3; export class ViewController { - state: ViewState = ViewState.New; + state = VIEW_STATE_NEW; nav?: any; element?: HTMLElement; delegate?: FrameworkDelegate; @@ -21,7 +19,7 @@ export class ViewController { ) {} async init(container: HTMLElement) { - this.state = ViewState.Attached; + this.state = VIEW_STATE_ATTACHED; if (!this.element) { const component = this.component; @@ -33,7 +31,7 @@ export class ViewController { * DOM WRITE */ _destroy() { - assert(this.state !== ViewState.Destroyed, 'view state must be ATTACHED'); + assert(this.state !== VIEW_STATE_DESTROYED, 'view state must be ATTACHED'); const element = this.element; if (element) { @@ -44,7 +42,7 @@ export class ViewController { } } this.nav = undefined; - this.state = ViewState.Destroyed; + this.state = VIEW_STATE_DESTROYED; } } diff --git a/core/src/components/router-outlet/route-outlet.tsx b/core/src/components/router-outlet/route-outlet.tsx index 870e24054a..5a374fd507 100644 --- a/core/src/components/router-outlet/route-outlet.tsx +++ b/core/src/components/router-outlet/route-outlet.tsx @@ -1,6 +1,6 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Prop, QueueApi, Watch } from '@stencil/core'; -import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate, Gesture, Mode, NavOutlet, RouteID, RouteWrite, RouterOutletOptions, SwipeGestureHandler } from '../../interface'; +import { Animation, AnimationBuilder, ComponentProps, ComponentRef, Config, FrameworkDelegate, Gesture, Mode, NavOutlet, RouteID, RouteWrite, RouterDirection, RouterOutletOptions, SwipeGestureHandler } from '../../interface'; import { transition } from '../../utils'; import { attachComponent, detachComponent } from '../../utils/framework-delegate'; @@ -102,10 +102,10 @@ export class RouterOutlet implements ComponentInterface, NavOutlet { /** @internal */ @Method() - async setRouteId(id: string, params: ComponentProps | undefined, direction: number): Promise { + async setRouteId(id: string, params: ComponentProps | undefined, direction: RouterDirection): Promise { const changed = await this.setRoot(id, params, { - duration: direction === 0 ? 0 : undefined, - direction: direction === -1 ? 'back' : 'forward', + duration: direction === 'root' ? 0 : undefined, + direction: direction === 'back' ? 'back' : 'forward', }); return { changed, diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index b6d0ade2a2..2eba8ce468 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -3,7 +3,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me import { BackButtonEvent, Config, RouteChain, RouterDirection, RouterEventDetail } from '../../interface'; import { debounce } from '../../utils/helpers'; -import { RouterIntent } from './utils/constants'; +import { ROUTER_INTENT_BACK, ROUTER_INTENT_FORWARD, ROUTER_INTENT_NONE } from './utils/constants'; import { printRedirects, printRoutes } from './utils/debug'; import { readNavState, waitUntilNavNode, writeNavState } from './utils/dom'; import { routeRedirect, routerIDsToChain, routerPathToChain } from './utils/matching'; @@ -97,9 +97,8 @@ export class Router implements ComponentInterface { console.debug('[ion-router] URL pushed -> updating nav', url, direction); const path = parsePath(url); - const intent = DIRECTION_TO_INTENT[direction]; - this.setPath(path, intent); - return this.writeNavStateRoot(path, intent); + this.setPath(path, direction); + return this.writeNavStateRoot(path, direction); } /** @@ -122,7 +121,7 @@ export class Router implements ComponentInterface { /** @internal */ @Method() - async navChanged(intent: number): Promise { + async navChanged(direction: RouterDirection): Promise { if (this.busy) { console.warn('[ion-router] router is busy, navChanged was cancelled'); return false; @@ -142,21 +141,21 @@ export class Router implements ComponentInterface { } console.debug('[ion-router] nav changed -> update URL', ids, path); - this.setPath(path, intent); + this.setPath(path, direction); - await this.safeWriteNavState(outlet, chain, RouterIntent.None, path, null, ids.length); + await this.safeWriteNavState(outlet, chain, ROUTER_INTENT_NONE, path, null, ids.length); return true; } private onRedirectChanged() { const path = this.getPath(); if (path && routeRedirect(path, readRedirects(this.el))) { - this.writeNavStateRoot(path, RouterIntent.None); + this.writeNavStateRoot(path, ROUTER_INTENT_NONE); } } private onRoutesChanged() { - return this.writeNavStateRoot(this.getPath(), RouterIntent.None); + return this.writeNavStateRoot(this.getPath(), ROUTER_INTENT_NONE); } private historyDirection() { @@ -172,15 +171,15 @@ export class Router implements ComponentInterface { this.lastState = state; if (state > lastState) { - return RouterIntent.Forward; + return ROUTER_INTENT_FORWARD; } else if (state < lastState) { - return RouterIntent.Back; + return ROUTER_INTENT_BACK; } else { - return RouterIntent.None; + return ROUTER_INTENT_NONE; } } - private async writeNavStateRoot(path: string[] | null, intent: RouterIntent): Promise { + private async writeNavStateRoot(path: string[] | null, direction: RouterDirection): Promise { if (!path) { console.error('[ion-router] URL is not part of the routing set'); return false; @@ -191,7 +190,7 @@ export class Router implements ComponentInterface { const redirect = routeRedirect(path, redirects); let redirectFrom: string[] | null = null; if (redirect) { - this.setPath(redirect.to!, intent); + this.setPath(redirect.to!, direction); redirectFrom = redirect.from; path = redirect.to!; } @@ -205,18 +204,18 @@ export class Router implements ComponentInterface { } // write DOM give - return this.safeWriteNavState(this.win.document.body, chain, intent, path, redirectFrom); + return this.safeWriteNavState(this.win.document.body, chain, direction, path, redirectFrom); } private async safeWriteNavState( - node: HTMLElement | undefined, chain: RouteChain, intent: RouterIntent, + node: HTMLElement | undefined, chain: RouteChain, direction: RouterDirection, path: string[], redirectFrom: string[] | null, index = 0 ): Promise { const unlock = await this.lock(); let changed = false; try { - changed = await this.writeNavState(node, chain, intent, path, redirectFrom, index); + changed = await this.writeNavState(node, chain, direction, path, redirectFrom, index); } catch (e) { console.error(e); } @@ -236,7 +235,7 @@ export class Router implements ComponentInterface { } private async writeNavState( - node: HTMLElement | undefined, chain: RouteChain, intent: RouterIntent, + node: HTMLElement | undefined, chain: RouteChain, direction: RouterDirection, path: string[], redirectFrom: string[] | null, index = 0 ): Promise { @@ -252,7 +251,7 @@ export class Router implements ComponentInterface { this.ionRouteWillChange.emit(routeEvent); } - const changed = await writeNavState(node, chain, intent, index); + const changed = await writeNavState(node, chain, direction, index); this.busy = false; if (changed) { @@ -266,9 +265,9 @@ export class Router implements ComponentInterface { return changed; } - private setPath(path: string[], intent: RouterIntent) { + private setPath(path: string[], direction: RouterDirection) { this.state++; - writePath(this.win.history, this.root, this.useHash, path, intent, this.state); + writePath(this.win.history, this.root, this.useHash, path, direction, this.state); } private getPath(): string[] | null { @@ -290,9 +289,3 @@ export class Router implements ComponentInterface { }; } } - -const DIRECTION_TO_INTENT = { - 'back': RouterIntent.Back, - 'root': RouterIntent.None, - 'forward': RouterIntent.Forward -}; diff --git a/core/src/components/router/test/path.spec.tsx b/core/src/components/router/test/path.spec.tsx index 6bc2749928..1c8306b3a2 100644 --- a/core/src/components/router/test/path.spec.tsx +++ b/core/src/components/router/test/path.spec.tsx @@ -1,4 +1,4 @@ -import { RouterIntent } from '../utils/constants'; +import { ROUTER_INTENT_FORWARD } from '../utils/constants'; import { RouteChain } from '../utils/interface'; import { chainToPath, generatePath, parsePath, readPath, writePath } from '../utils/path'; @@ -178,61 +178,61 @@ describe('readPath', () => { describe('writePath', () => { it('should write root path (no hash)', () => { const history = mockHistory(); - writePath(history, '', false, [''], RouterIntent.Forward, 123); + writePath(history, '', false, [''], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '/'); - writePath(history, '', false, ['schedule'], RouterIntent.Forward, 123); + writePath(history, '', false, ['schedule'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '/schedule'); - writePath(history, '/', false, [''], RouterIntent.Forward, 123); + writePath(history, '/', false, [''], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '/'); - writePath(history, '/', false, ['to', 'schedule'], RouterIntent.Forward, 123); + writePath(history, '/', false, ['to', 'schedule'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '/to/schedule'); }); it('should write non root path (no hash)', () => { const history = mockHistory(); - writePath(history, '/path', false, [''], RouterIntent.Forward, 2); + writePath(history, '/path', false, [''], ROUTER_INTENT_FORWARD, 2); expect(history.pushState).toHaveBeenCalledWith(2, '', '/path'); - writePath(history, '/path', false, ['to', 'page'], RouterIntent.Forward, 2); + writePath(history, '/path', false, ['to', 'page'], ROUTER_INTENT_FORWARD, 2); expect(history.pushState).toHaveBeenCalledWith(2, '', '/path/to/page'); - writePath(history, 'path/to', false, ['second', 'page'], RouterIntent.Forward, 2); + writePath(history, 'path/to', false, ['second', 'page'], ROUTER_INTENT_FORWARD, 2); expect(history.pushState).toHaveBeenCalledWith(2, '', '/path/to/second/page'); - writePath(history, '/path/to/', false, ['second', 'page'], RouterIntent.Forward, 2); + writePath(history, '/path/to/', false, ['second', 'page'], ROUTER_INTENT_FORWARD, 2); expect(history.pushState).toHaveBeenCalledWith(2, '', '/path/to/second/page'); }); it('should write root path (no hash)', () => { const history = mockHistory(); - writePath(history, '', true, [''], RouterIntent.Forward, 123); + writePath(history, '', true, [''], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/'); - writePath(history, '', true, ['schedule'], RouterIntent.Forward, 123); + writePath(history, '', true, ['schedule'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/schedule'); - writePath(history, '/', true, [''], RouterIntent.Forward, 123); + writePath(history, '/', true, [''], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/'); - writePath(history, '/', true, ['to', 'schedule'], RouterIntent.Forward, 123); + writePath(history, '/', true, ['to', 'schedule'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/to/schedule'); }); it('should write non root path (no hash)', () => { const history = mockHistory(); - writePath(history, '/path', true, [''], RouterIntent.Forward, 123); + writePath(history, '/path', true, [''], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/path'); - writePath(history, '/path', true, ['to', 'page'], RouterIntent.Forward, 123); + writePath(history, '/path', true, ['to', 'page'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/path/to/page'); - writePath(history, 'path/to', true, ['second', 'page'], RouterIntent.Forward, 123); + writePath(history, 'path/to', true, ['second', 'page'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/path/to/second/page'); - writePath(history, '/path/to/', true, ['second', 'page'], RouterIntent.Forward, 123); + writePath(history, '/path/to/', true, ['second', 'page'], ROUTER_INTENT_FORWARD, 123); expect(history.pushState).toHaveBeenCalledWith(123, '', '#/path/to/second/page'); }); }); diff --git a/core/src/components/router/utils/constants.ts b/core/src/components/router/utils/constants.ts index 75de3b7d3e..7f47d466b3 100644 --- a/core/src/components/router/utils/constants.ts +++ b/core/src/components/router/utils/constants.ts @@ -1,6 +1,4 @@ -export const enum RouterIntent { - None = 0, - Forward = 1, - Back = -1, -} +export const ROUTER_INTENT_NONE = 'root'; +export const ROUTER_INTENT_FORWARD = 'forward'; +export const ROUTER_INTENT_BACK = 'back'; diff --git a/core/src/components/router/utils/dom.ts b/core/src/components/router/utils/dom.ts index 0e728763ed..e92300f595 100644 --- a/core/src/components/router/utils/dom.ts +++ b/core/src/components/router/utils/dom.ts @@ -1,11 +1,11 @@ -import { NavOutletElement, RouteChain, RouteID } from '../../../interface'; +import { NavOutletElement, RouteChain, RouteID, RouterDirection } from '../../../interface'; -import { RouterIntent } from './constants'; +import { ROUTER_INTENT_NONE } from './constants'; export async function writeNavState( root: HTMLElement | undefined, chain: RouteChain, - intent: RouterIntent, + direction: RouterDirection, index: number, changed = false ): Promise { @@ -20,17 +20,17 @@ export async function writeNavState( await outlet.componentOnReady(); const route = chain[index]; - const result = await outlet.setRouteId(route.id, route.params, intent); + const result = await outlet.setRouteId(route.id, route.params, direction); // if the outlet changed the page, reset navigation to neutral (no direction) // this means nested outlets will not animate if (result.changed) { - intent = RouterIntent.None; + direction = ROUTER_INTENT_NONE; changed = true; } // recursively set nested outlets - changed = await writeNavState(result.element, chain, intent, index + 1, changed); + changed = await writeNavState(result.element, chain, direction, index + 1, changed); // once all nested outlets are visible let's make the parent visible too, // using markVisible prevents flickering diff --git a/core/src/components/router/utils/interface.ts b/core/src/components/router/utils/interface.ts index a1aa379f34..16b8eeb5a5 100644 --- a/core/src/components/router/utils/interface.ts +++ b/core/src/components/router/utils/interface.ts @@ -1,7 +1,7 @@ import { ComponentProps } from '../../../interface'; export interface NavOutlet { - setRouteId(id: string, params: ComponentProps | undefined, direction: number): Promise; + setRouteId(id: string, params: ComponentProps | undefined, direction: RouterDirection): Promise; getRouteId(): Promise; } diff --git a/core/src/components/router/utils/path.ts b/core/src/components/router/utils/path.ts index b0c05b6539..16f91baaa3 100644 --- a/core/src/components/router/utils/path.ts +++ b/core/src/components/router/utils/path.ts @@ -1,6 +1,6 @@ -import { RouteChain } from '../../../interface'; +import { RouteChain, RouterDirection } from '../../../interface'; -import { RouterIntent } from './constants'; +import { ROUTER_INTENT_FORWARD } from './constants'; export function generatePath(segments: string[]): string { const path = segments @@ -28,7 +28,7 @@ export function chainToPath(chain: RouteChain): string[] | null { return path; } -export function writePath(history: History, root: string, useHash: boolean, path: string[], intent: RouterIntent, state: number) { +export function writePath(history: History, root: string, useHash: boolean, path: string[], direction: RouterDirection, state: number) { let url = generatePath([ ...parsePath(root), ...path @@ -36,7 +36,7 @@ export function writePath(history: History, root: string, useHash: boolean, path if (useHash) { url = '#' + url; } - if (intent === RouterIntent.Forward) { + if (direction === ROUTER_INTENT_FORWARD) { history.pushState(state, '', url); } else { history.replaceState(state, '', url); diff --git a/core/src/components/tabs/tabs.tsx b/core/src/components/tabs/tabs.tsx index 8e0791509f..19008f977a 100644 --- a/core/src/components/tabs/tabs.tsx +++ b/core/src/components/tabs/tabs.tsx @@ -187,7 +187,7 @@ export class Tabs implements NavOutlet { if (this.useRouter) { const router = this.doc.querySelector('ion-router'); if (router) { - return router.navChanged(1); + return router.navChanged('forward'); } } return Promise.resolve(false); diff --git a/core/src/components/virtual-scroll/constants.ts b/core/src/components/virtual-scroll/constants.ts new file mode 100644 index 0000000000..6f05ddce7e --- /dev/null +++ b/core/src/components/virtual-scroll/constants.ts @@ -0,0 +1,7 @@ +export const CELL_TYPE_ITEM = 'item'; +export const CELL_TYPE_HEADER = 'header'; +export const CELL_TYPE_FOOTER = 'footer'; + +export const NODE_CHANGE_NONE = 0; +export const NODE_CHANGE_POSITION = 1; +export const NODE_CHANGE_CELL = 2; diff --git a/core/src/components/virtual-scroll/test/virtual-scroll-utils.spec.ts b/core/src/components/virtual-scroll/test/virtual-scroll-utils.spec.ts index e5691417e2..36efc1c9f5 100644 --- a/core/src/components/virtual-scroll/test/virtual-scroll-utils.spec.ts +++ b/core/src/components/virtual-scroll/test/virtual-scroll-utils.spec.ts @@ -1,6 +1,6 @@ import { HeaderFn, ItemHeightFn, VirtualNode } from '../../../interface'; -import { CellType } from '../virtual-scroll-interface'; import { Range, calcCells, calcHeightIndex, getRange, getShouldUpdate, getViewport, positionForIndex, resizeBuffer, updateVDom } from '../virtual-scroll-utils'; +import { CELL_TYPE_ITEM, CELL_TYPE_HEADER, CELL_TYPE_FOOTER } from '../constants'; describe('getViewport', () => { it('should return viewport without margin', () => { @@ -149,7 +149,7 @@ describe('calcCells', () => { const cells = calcCells(items, undefined, undefined, undefined, 10, 20, 30, 0, 0, items.length); expect(cells).toEqual([ { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: '0', i: 0, index: 0, @@ -158,7 +158,7 @@ describe('calcCells', () => { visible: false, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: 2, i: 1, index: 1, @@ -167,7 +167,7 @@ describe('calcCells', () => { visible: false, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: 'hola', i: 2, index: 2, @@ -176,7 +176,7 @@ describe('calcCells', () => { visible: false, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: { data: 'hello' }, i: 3, index: 3, @@ -200,7 +200,7 @@ describe('calcCells', () => { expect(called).toEqual(3); expect(cells).toEqual([ { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: 10, i: 0, index: 0, @@ -209,7 +209,7 @@ describe('calcCells', () => { visible: true, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: 9, i: 1, index: 1, @@ -218,7 +218,7 @@ describe('calcCells', () => { visible: true, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: 8, i: 2, index: 2, @@ -258,7 +258,7 @@ describe('calcCells', () => { expect(footerCalled).toEqual(3); expect(cells).toEqual([ { - type: CellType.Header, + type: CELL_TYPE_HEADER, value: 'my header', i: 0, index: 0, @@ -267,7 +267,7 @@ describe('calcCells', () => { visible: false, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: '10', i: 1, index: 0, @@ -276,7 +276,7 @@ describe('calcCells', () => { visible: true, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: '9', i: 2, index: 1, @@ -285,7 +285,7 @@ describe('calcCells', () => { visible: true, }, { - type: CellType.Item, + type: CELL_TYPE_ITEM, value: '8', i: 3, index: 2, @@ -294,7 +294,7 @@ describe('calcCells', () => { visible: true, }, { - type: CellType.Footer, + type: CELL_TYPE_FOOTER, value: 'my footer', i: 4, index: 2, diff --git a/core/src/components/virtual-scroll/virtual-scroll-interface.ts b/core/src/components/virtual-scroll/virtual-scroll-interface.ts index 852c43d5cf..0ee68d3ae7 100644 --- a/core/src/components/virtual-scroll/virtual-scroll-interface.ts +++ b/core/src/components/virtual-scroll/virtual-scroll-interface.ts @@ -1,16 +1,4 @@ -export const enum CellType { - Item, - Header, - Footer -} - -export const enum NodeChange { - NoChange, - Position, - Cell, -} - export interface Cell { i: number; index: number; @@ -29,6 +17,8 @@ export interface VirtualNode { visible: boolean; } +export type CellType = 'item' | 'header' | 'footer'; +export type NodeChange = number; export type HeaderFn = (item: any, index: number, items: any[]) => string | null | undefined; export type ItemHeightFn = (item: any, index: number) => number; export type ItemRenderFn = (el: HTMLElement | null, cell: Cell, domIndex: number) => HTMLElement; diff --git a/core/src/components/virtual-scroll/virtual-scroll-utils.ts b/core/src/components/virtual-scroll/virtual-scroll-utils.ts index 6ea895a50e..7ef3ae64a8 100644 --- a/core/src/components/virtual-scroll/virtual-scroll-utils.ts +++ b/core/src/components/virtual-scroll/virtual-scroll-utils.ts @@ -1,6 +1,7 @@ import { Cell, HeaderFn, ItemHeightFn, ItemRenderFn, VirtualNode } from '../../interface'; -import { CellType, NodeChange } from './virtual-scroll-interface'; +import { CELL_TYPE_FOOTER, CELL_TYPE_HEADER, CELL_TYPE_ITEM, NODE_CHANGE_CELL, NODE_CHANGE_NONE, NODE_CHANGE_POSITION } from './constants'; +import { CellType } from './virtual-scroll-interface'; export interface Viewport { top: number; @@ -17,7 +18,7 @@ const MIN_READS = 2; export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: Cell[], range: Range) { // reset dom for (const node of dom) { - node.change = NodeChange.NoChange; + node.change = NODE_CHANGE_NONE; node.d = true; } @@ -32,7 +33,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: const top = heightIndex[i]; if (top !== node.top) { node.top = top; - node.change = NodeChange.Position; + node.change = NODE_CHANGE_POSITION; } node.d = false; } else { @@ -48,7 +49,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: const index = cell.index; if (node) { node.d = false; - node.change = NodeChange.Cell; + node.change = NODE_CHANGE_CELL; node.cell = cell; node.top = heightIndex[index]; } else { @@ -56,7 +57,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: d: false, cell, visible: true, - change: NodeChange.Cell, + change: NODE_CHANGE_CELL, top: heightIndex[index], }); } @@ -64,7 +65,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: dom .filter(n => n.d && n.top !== -9999) .forEach(n => { - n.change = NodeChange.Position; + n.change = NODE_CHANGE_POSITION; n.top = -9999; }); } @@ -83,7 +84,7 @@ export function doRender( const cell = node.cell; // the cell change, the content must be updated - if (node.change === NodeChange.Cell) { + if (node.change === NODE_CHANGE_CELL) { if (i < childrenNu) { child = children[i] as HTMLElement; nodeRender(child, cell, i); @@ -99,7 +100,7 @@ export function doRender( } // only update position when it changes - if (node.change !== NodeChange.NoChange) { + if (node.change !== NODE_CHANGE_NONE) { child.style.transform = `translate3d(0,${node.top}px,0)`; } @@ -132,9 +133,9 @@ function createNode(el: HTMLElement, type: CellType): HTMLElement | null { function getTemplate(el: HTMLElement, type: CellType): HTMLTemplateElement | null { switch (type) { - case CellType.Item: return el.querySelector('template:not([name])'); - case CellType.Header: return el.querySelector('template[name=header]'); - case CellType.Footer: return el.querySelector('template[name=footer]'); + case CELL_TYPE_ITEM: return el.querySelector('template:not([name])'); + case CELL_TYPE_HEADER: return el.querySelector('template[name=header]'); + case CELL_TYPE_FOOTER: return el.querySelector('template[name=footer]'); } } @@ -220,7 +221,7 @@ export function calcCells( if (value != null) { cells.push({ i: j++, - type: CellType.Header, + type: CELL_TYPE_HEADER, value, index: i, height: approxHeaderHeight, @@ -232,7 +233,7 @@ export function calcCells( cells.push({ i: j++, - type: CellType.Item, + type: CELL_TYPE_ITEM, value: item, index: i, height: itemHeight ? itemHeight(item, i) : approxItemHeight, @@ -245,7 +246,7 @@ export function calcCells( if (value != null) { cells.push({ i: j++, - type: CellType.Footer, + type: CELL_TYPE_FOOTER, value, index: i, height: approxFooterHeight, @@ -283,7 +284,7 @@ export function resizeBuffer(buf: Uint32Array | undefined, len: number) { } export function positionForIndex(index: number, cells: Cell[], heightIndex: Uint32Array): number { - const cell = cells.find(c => c.type === CellType.Item && c.index === index); + const cell = cells.find(c => c.type === CELL_TYPE_ITEM && c.index === index); if (cell) { return heightIndex[cell.i]; } diff --git a/core/src/components/virtual-scroll/virtual-scroll.tsx b/core/src/components/virtual-scroll/virtual-scroll.tsx index 4ace465926..76ddc3c62f 100644 --- a/core/src/components/virtual-scroll/virtual-scroll.tsx +++ b/core/src/components/virtual-scroll/virtual-scroll.tsx @@ -2,7 +2,7 @@ import { Component, ComponentInterface, Element, EventListenerEnable, Functional import { Cell, DomRenderFn, HeaderFn, ItemHeightFn, ItemRenderFn, VirtualNode } from '../../interface'; -import { CellType } from './virtual-scroll-interface'; +import { CELL_TYPE_FOOTER, CELL_TYPE_HEADER, CELL_TYPE_ITEM } from './constants'; import { Range, calcCells, calcHeightIndex, doRender, findCellIndex, getRange, getShouldUpdate, getViewport, inplaceUpdate, positionForIndex, resizeBuffer, updateVDom } from './virtual-scroll-utils'; @Component({ @@ -411,9 +411,9 @@ export class VirtualScroll implements ComponentInterface { private renderVirtualNode(node: VirtualNode) { const { type, value, index } = node.cell; switch (type) { - case CellType.Item: return this.renderItem!(value, index); - case CellType.Header: return this.renderHeader!(value, index); - case CellType.Footer: return this.renderFooter!(value, index); + case CELL_TYPE_ITEM: return this.renderItem!(value, index); + case CELL_TYPE_HEADER: return this.renderHeader!(value, index); + case CELL_TYPE_FOOTER: return this.renderFooter!(value, index); } } diff --git a/core/src/index.ts b/core/src/index.ts index 699c210e96..03a860c41e 100644 --- a/core/src/index.ts +++ b/core/src/index.ts @@ -1,14 +1,2 @@ - -// lifecycle -export const enum ViewLifecycle { - WillEnter = 'ionViewWillEnter', - DidEnter = 'ionViewDidEnter', - WillLeave = 'ionViewWillLeave', - DidLeave = 'ionViewDidLeave', - WillUnload = 'ionViewWillUnload', -} - -// util functions export * from './utils/platform'; export * from './utils/config'; -export * from './utils/gesture/swipe-back'; diff --git a/core/src/interface.d.ts b/core/src/interface.d.ts index 795e7fa221..af60a9b9e3 100644 --- a/core/src/interface.d.ts +++ b/core/src/interface.d.ts @@ -4,18 +4,18 @@ export * from './index'; export * from './components/animation-controller/animation-interface'; export * from './components/alert/alert-interface'; export * from './components/action-sheet/action-sheet-interface'; +export * from './components/content/content-interface'; export * from './components/datetime/datetime-interface'; +export * from './components/loading/loading-interface'; export * from './components/menu/menu-interface'; export * from './components/modal/modal-interface'; -export * from './components/picker/picker-interface'; -export * from './components/loading/loading-interface'; -export * from './components/popover/popover-interface'; export * from './components/nav/nav-interface'; -export * from './components/router/utils/interface'; +export * from './components/picker/picker-interface'; +export * from './components/popover/popover-interface'; export * from './components/range/range-interface'; +export * from './components/router/utils/interface'; export * from './components/refresher/refresher-interface'; export * from './components/reorder-group/reorder-group-interface'; -export * from './components/content/content-interface'; export * from './components/segment-button/segment-button-interface'; export * from './components/select/select-interface'; export * from './components/select-popover/select-popover-interface'; @@ -26,7 +26,6 @@ export * from './components/virtual-scroll/virtual-scroll-interface'; // TODO: review how this types are exported // Other types -export * from './components/nav/view-controller'; export { Gesture, GestureDetail } from './utils/gesture/gesture'; diff --git a/core/src/utils/transition.ts b/core/src/utils/transition.ts index dcfa5daf51..85d6b20f58 100644 --- a/core/src/utils/transition.ts +++ b/core/src/utils/transition.ts @@ -1,6 +1,6 @@ import { QueueApi } from '@stencil/core'; -import { ViewLifecycle } from '..'; +import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '../components/nav/constants'; import { Animation, AnimationBuilder, NavDirection, NavOptions } from '../interface'; const iosTransitionAnimation = () => import('./animations/ios.transition'); @@ -148,22 +148,22 @@ function playTransition(trans: Animation, opts: TransitionOptions): Promise