From 89c0a0ef090dc20ebebc8a931f8b4806b56f1f4d Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Wed, 23 Sep 2015 16:57:25 -0500 Subject: [PATCH] refactor(): rename ViewController/ViewItem Rename ViewController to NavController, ViewItem to ViewController --- demos/native/index.ts | 2 +- demos/navigation/index.ts | 12 +- demos/sink/index.ts | 2 +- ionic/components.ts | 2 +- ionic/components/app/structure.scss | 14 + ionic/components/item/item-options.ts | 17 - ionic/components/item/item-swipe-buttons.ts | 90 -- ionic/components/item/item.ts | 3 +- ionic/components/menu/menu-toggle.ts | 10 +- ionic/components/nav-bar/nav-bar.ts | 18 +- ionic/components/nav/anchors.ts | 6 +- ionic/components/nav/nav-controller.ts | 776 ++++++++++++++++- ionic/components/nav/nav-router.ts | 26 +- ionic/components/nav/nav.ts | 10 +- ionic/components/nav/pane.ts | 22 +- ionic/components/{view => nav}/swipe-back.ts | 10 +- ionic/components/nav/test/basic/index.ts | 12 +- ionic/components/nav/test/routing/index.ts | 14 +- ionic/components/nav/test/routing/view1.html | 2 +- ionic/components/nav/test/routing/view2.html | 2 +- ionic/components/nav/test/routing/view3.html | 2 +- .../view-item.ts => nav/view-controller.ts} | 39 +- ionic/components/tabs/tab.ts | 38 +- ionic/components/tabs/tabs.ts | 62 +- ionic/components/view/view-controller.ts | 780 ------------------ ionic/components/view/view.scss | 17 - ionic/ionic.core.scss | 3 +- ionic/transitions/transition.ts | 30 +- 28 files changed, 930 insertions(+), 1091 deletions(-) delete mode 100644 ionic/components/item/item-options.ts delete mode 100644 ionic/components/item/item-swipe-buttons.ts rename ionic/components/{view => nav}/swipe-back.ts (69%) rename ionic/components/{view/view-item.ts => nav/view-controller.ts} (90%) delete mode 100644 ionic/components/view/view-controller.ts delete mode 100644 ionic/components/view/view.scss diff --git a/demos/native/index.ts b/demos/native/index.ts index b129a21690..da9c1207c3 100644 --- a/demos/native/index.ts +++ b/demos/native/index.ts @@ -74,6 +74,6 @@ class MyApp { menu.close(); let nav = this.app.getComponent('myNav'); - nav.setItems([page.page]); + nav.setViews([page.page]); } } diff --git a/demos/navigation/index.ts b/demos/navigation/index.ts index b67fece545..632fa32380 100644 --- a/demos/navigation/index.ts +++ b/demos/navigation/index.ts @@ -12,7 +12,7 @@ import {NavParams, NavController} from 'ionic/ionic'; '

{{title}}

' + '

' + '

' + - '

' + + '

' + '' }) class FirstPage { @@ -29,11 +29,11 @@ class FirstPage { } } - setItems() { + setViews() { let items = [ ThirdPage ]; - this.nav.setItems(items); + this.nav.setViews(items); } push() { @@ -52,7 +52,7 @@ class FirstPage {

-

+

` }) @@ -66,12 +66,12 @@ class SecondPage { console.log('Second page params:', params); } - setItems() { + setViews() { let items = [ FirstPage, ThirdPage ]; - this.nav.setItems(items); + this.nav.setViews(items); } pop() { diff --git a/demos/sink/index.ts b/demos/sink/index.ts index 27b082b229..ec1128d33a 100644 --- a/demos/sink/index.ts +++ b/demos/sink/index.ts @@ -100,6 +100,6 @@ class MyApp { menu.close(); let nav = this.app.getComponent('myNav'); - nav.setItems([component.component]); + nav.setViews([component.component]); } } diff --git a/ionic/components.ts b/ionic/components.ts index cd2504885a..75e295add6 100644 --- a/ionic/components.ts +++ b/ionic/components.ts @@ -20,6 +20,7 @@ export * from 'ionic/components/show-hide-when/show-hide-when' export * from 'ionic/components/modal/modal' export * from 'ionic/components/nav/nav' export * from 'ionic/components/nav/nav-controller' +export * from 'ionic/components/nav/view-controller' export * from 'ionic/components/nav/nav-push' export * from 'ionic/components/nav/nav-router' export * from 'ionic/components/nav-bar/nav-bar' @@ -34,4 +35,3 @@ export * from 'ionic/components/switch/switch' export * from 'ionic/components/tabs/tabs' export * from 'ionic/components/tabs/tab' export * from 'ionic/components/toolbar/toolbar' -export * from 'ionic/components/view/view-item' diff --git a/ionic/components/app/structure.scss b/ionic/components/app/structure.scss index 1925a08e65..8bd47a16de 100644 --- a/ionic/components/app/structure.scss +++ b/ionic/components/app/structure.scss @@ -130,6 +130,20 @@ ion-pane { order: $flex-order-view-content; } +ion-view { + display: flex; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + flex-direction: column; + + background-color: white; + + transform: translateZ(0px); +} + [hidden], template, root-anchor { diff --git a/ionic/components/item/item-options.ts b/ionic/components/item/item-options.ts deleted file mode 100644 index 44362a574f..0000000000 --- a/ionic/components/item/item-options.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * TODO - */ -@Decorator({ - selector: 'ion-primary-options' -}) -export class ItemPrimaryOptions { -} - -/** - * TODO - */ -@Decorator({ - selector: 'ion-secondary-options' -}) -export class ItemSecondaryOptions { -} diff --git a/ionic/components/item/item-swipe-buttons.ts b/ionic/components/item/item-swipe-buttons.ts deleted file mode 100644 index 911b1808dd..0000000000 --- a/ionic/components/item/item-swipe-buttons.ts +++ /dev/null @@ -1,90 +0,0 @@ -import {ElementRef, Host, Directive} from 'angular2/angular2'; - -import {Item} from 'ionic/components/item/item'; -import {SlideGesture} from 'ionic/gestures/slide-gesture'; - -/** - * @name ionPrimarySwipeButtons - * @description - * Creates a swipeable button inside a list item, that is visible when the item is swiped to the left by the user. Swiped open buttons can be hidden with `setOpen(false)`. - * - * @usage - * TODO - */ -@Directive({ - selector: 'ion-primary-swipe-buttons' -}) -export class ItemPrimarySwipeButtons { - /** - * @param {ElementRef} elementRef A reference to the component's DOM element. - * @param {Item} item The list item containing the swipeable buttons. - */ - constructor( - elementRef: ElementRef, - @Host() item: Item - ) { - item.primarySwipeButtons = this; - this.ele = elementRef.nativeElement; - this.item = item; - this.gesture = new ItemSlideGesture(this); - this.gesture.listen(); - } - - /** - * @param {boolean} isOpen Whether or not the button should be set to open/visible. - */ - setOpen(isOpen) { - if (isOpen !== this.isOpen) { - this.isOpen = isOpen; - requestAnimationFrame(() => { - this.ele.classList[isOpen?'add':'remove'](isOpen); - }); - } - } -} - -/** - * TODO - */ -@Directive({ - selector: 'ion-secondary-swipe-buttons' -}) -export class ItemSecondarySwipeButtons { -} - -class ItemSlideGesture extends SlideGesture { - constructor(buttons) { - super(buttons.item.ele) - this.buttons = buttons - } - - getSlideBoundaries() { - return { - min: -this.buttons.ele.offsetWidth, - max: 0, - }; - } - - getElementStartPos(slide, ev) { - return this.buttons.isOpen ? slide.max : slide.min; - } - - onSlideBeforeStart() { - this.buttons.ele.classList.add('changing') - this.buttons.ele.classList.add('no-transition') - return new Promise(resolve => { - requestAnimationFrame(resolve) - }) - } - onSlide(slide, ev) { - this.buttons.ele.style.transform = 'translate3d(' + slide.distance + 'px,0,0)'; - } - onSlideEnd(slide, ev) { - this.buttons.ele.style.transform = '' - this.buttons.ele.classList.remove('no-transition') - if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) { - this.buttons.setOpen(!this.buttons.isOpen); - } - } - -} diff --git a/ionic/components/item/item.ts b/ionic/components/item/item.ts index a803688d8f..bac77e55a8 100644 --- a/ionic/components/item/item.ts +++ b/ionic/components/item/item.ts @@ -1,9 +1,8 @@ import {Component, Directive, View, ElementRef, NgIf, ViewQuery, QueryList} from 'angular2/angular2'; -import {ItemPrimaryOptions, ItemSecondaryOptions} from './item-options'; -import {ItemPrimarySwipeButtons, ItemSecondarySwipeButtons} from './item-swipe-buttons'; import {dom} from 'ionic/util'; + /** * @name ionItem * @description diff --git a/ionic/components/menu/menu-toggle.ts b/ionic/components/menu/menu-toggle.ts index e88dfdc5e8..d476d1c518 100644 --- a/ionic/components/menu/menu-toggle.ts +++ b/ionic/components/menu/menu-toggle.ts @@ -2,7 +2,7 @@ import {Directive, ElementRef, Optional} from 'angular2/angular2'; import {Ion} from '../ion'; import {IonicApp} from '../app/app'; -import {ViewItem} from '../view/view-item'; +import {ViewController} from '../nav/view-controller'; import {Navbar} from '../nav-bar/nav-bar'; @@ -24,12 +24,12 @@ export class MenuToggle extends Ion { constructor( app: IonicApp, elementRef: ElementRef, - @Optional() item: ViewItem, + @Optional() viewCtrl: ViewController, @Optional() navbar: Navbar ) { super(elementRef, null); this.app = app; - this.item = item; + this.viewCtrl = viewCtrl; this.withinNavbar = !!navbar; } @@ -45,8 +45,8 @@ export class MenuToggle extends Ion { } get isHidden() { - if (this.withinNavbar && this.item) { - return !this.item.isRoot(); + if (this.withinNavbar && this.viewCtrl) { + return !this.viewCtrl.isRoot(); } return false; } diff --git a/ionic/components/nav-bar/nav-bar.ts b/ionic/components/nav-bar/nav-bar.ts index 5e992a575e..d21368c0a1 100644 --- a/ionic/components/nav-bar/nav-bar.ts +++ b/ionic/components/nav-bar/nav-bar.ts @@ -5,8 +5,8 @@ import {ToolbarBase} from '../toolbar/toolbar'; import {IonicConfig} from '../../config/config'; import {IonicView} from '../../config/decorators'; import {IonicApp} from '../app/app'; -import {ViewItem} from '../view/view-item'; -import {ViewController} from '../view/view-controller'; +import {ViewController} from '../nav/view-controller'; +import {NavController} from '../nav/nav-controller'; @Directive({ @@ -17,19 +17,19 @@ import {ViewController} from '../view/view-controller'; }) class BackButton extends Ion { constructor( - @Optional() viewCtrl: ViewController, + @Optional() navCtrl: NavController, elementRef: ElementRef, @Optional() @Inject(forwardRef(() => Navbar)) navbar: Navbar ) { super(elementRef, null); - this.viewCtrl = viewCtrl; + this.navCtrl = navCtrl; navbar && navbar.setBackButtonRef(elementRef); } goBack(ev) { ev.stopPropagation(); ev.preventDefault(); - this.viewCtrl && this.viewCtrl.pop(); + this.navCtrl && this.navCtrl.pop(); } } @@ -73,14 +73,14 @@ class BackButtonText extends Ion { export class Navbar extends ToolbarBase { constructor( app: IonicApp, - @Optional() item: ViewItem, + @Optional() viewCtrl: ViewController, elementRef: ElementRef, config: IonicConfig ) { super(elementRef, config); this.app = app; - item && item.navbarView(this); + viewCtrl && viewCtrl.navbarView(this); this.bbIcon = config.setting('backButtonIcon'); this.bbDefault = config.setting('backButtonText'); @@ -119,9 +119,9 @@ export class Navbar extends ToolbarBase { }) export class NavbarTemplate { constructor( - @Optional() item: ViewItem, + @Optional() viewCtrl: ViewController, @Optional() templateRef: TemplateRef ) { - item && item.addTemplateRef('navbar', templateRef); + viewCtrl && viewCtrl.addTemplateRef('navbar', templateRef); } } diff --git a/ionic/components/nav/anchors.ts b/ionic/components/nav/anchors.ts index dc214497eb..64bb3cf6b6 100644 --- a/ionic/components/nav/anchors.ts +++ b/ionic/components/nav/anchors.ts @@ -2,7 +2,7 @@ import {Component, View, Directive, Host, ElementRef, forwardRef, Inject} from ' import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref'; import {Pane} from './pane'; -import {ViewController} from '../view/view-controller'; +import {NavController} from './nav-controller'; @Directive({selector: 'template[pane-anchor]'}) @@ -32,10 +32,10 @@ export class PaneContentAnchor { }) class NavBarAnchor { constructor( - @Inject(forwardRef(() => ViewController)) viewCtrl: ViewController, + @Inject(forwardRef(() => NavController)) navCtrl: NavController, viewContainerRef: ViewContainerRef ) { - viewCtrl.navbarViewContainer(viewContainerRef); + navCtrl.navbarViewContainer(viewContainerRef); } } diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts index 1b6c75c10a..457d2a8a6a 100644 --- a/ionic/components/nav/nav-controller.ts +++ b/ionic/components/nav/nav-controller.ts @@ -1,51 +1,783 @@ -import {extend} from '../../util/util'; +import {Compiler, ElementRef, Injector, bind, NgZone} from 'angular2/angular2'; +import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader'; +import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; + +import {Ion} from '../ion'; +import {IonicConfig} from '../../config/config'; +import {IonicApp} from '../app/app'; +import {ViewController} from './view-controller'; +import {PaneController} from './pane'; +import {Transition} from '../../transitions/transition'; +import {SwipeBackGesture} from './swipe-back'; +import * as util from 'ionic/util'; /** * TODO */ -export class NavController { +export class NavController extends Ion { + + constructor( + parentnavCtrl: NavController, + injector: Injector, + elementRef: ElementRef, + zone: NgZone + ) { + let config = injector.get(IonicConfig); + super(elementRef, config); + + this.parent = parentnavCtrl; + + this.compiler = injector.get(Compiler); + this.loader = injector.get(DynamicComponentLoader); + this.viewMngr = injector.get(AppViewManager); + this.app = injector.get(IonicApp); + this.config = config; + this.zone = zone; + + this.views = []; + this.panes = new PaneController(this); + + this._sbTrans = null; + this.sbEnabled = config.setting('swipeBackEnabled') || false; + this.sbThreshold = config.setting('swipeBackThreshold') || 40 + + this.id = ++ctrlIds; + this._ids = -1; + this.zIndexes = -1; + + // build a new injector for child ViewControllers to use + this.bindings = Injector.resolve([ + bind(NavController).toValue(this) + ]); + } + /** * TODO - * @param {TODO} nav TODO + * @param {TODO} componentType TODO + * @param {TODO} [params={}] TODO + * @param {TODO} [opts={}] TODO + * @returns {Promise} TODO */ - constructor(nav) { - this._nav = nav; + push(componentType, params = {}, opts = {}) { + if (!componentType) { + return Promise.reject(); + } + if (typeof componentType !== 'function') { + throw 'Loading component must be a component class, not "' + componentType.toString() + '"'; + } + + let resolve; + let promise = new Promise(res => { resolve = res; }); + + // do not animate if this is the first in the stack + if (!this.views.length) { + opts.animation = 'none'; + } + + // default the direction to "forward" + opts.direction = opts.direction || 'forward'; + + // the active view is going to be the leaving one (if one exists) + let leavingView = this.getActive() || new ViewController(); + leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : true); + leavingView.shouldDestroy = !leavingView.shouldCache; + if (leavingView.shouldDestroy) { + leavingView.willUnload(); + } + + // create a new ViewController + let enteringView = new ViewController(this, componentType, params); + + // add the view to the stack + this.add(enteringView); + + if (this.router) { + // notify router of the state change + this.router.stateChange('push', enteringView, params); + } + + // start the transition + this.transition(enteringView, leavingView, opts, () => { + resolve(); + }); + + return promise; } /** - * Set the history stack to match the list of component items. - * @param {TODO} items TODO - * @return {TODO} TODO + * TODO + * @param {TODO} [opts={}] TODO + * @returns {Promise} TODO */ - setItems(items) { - return this._nav.setItems(items); + pop(opts = {}) { + if (!this.canGoBack()) { + return Promise.reject(); + } + + let resolve; + let promise = new Promise(res => { resolve = res; }); + + // default the direction to "back" + opts.direction = opts.direction || 'back'; + + // get the active view and set that it is staged to be leaving + // was probably the one popped from the stack + let leavingView = this.getActive() || new ViewController(); + leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : false); + leavingView.shouldDestroy = !leavingView.shouldCache; + if (leavingView.shouldDestroy) { + leavingView.willUnload(); + } + + // the entering view is now the new last view + // Note: we might not have an entering view if this is the + // only view on the history stack. + let enteringView = this.getPrevious(leavingView); + if (enteringView) { + if (this.router) { + // notify router of the state change + this.router.stateChange('pop', enteringView); + } + + // start the transition + this.transition(enteringView, leavingView, opts, () => { + // transition completed, destroy the leaving view + resolve(); + }); + + } else { + this._transComplete(); + resolve(); + } + + return promise; } /** - * Clear the history stack. - * @return {TODO} TODO + * Set the view stack to reflect the given component classes. + * @param {TODO} components TODO + * @param {TODO} [opts={}] TODO + * @returns {Promise} TODO */ - clear() { - return this._nav.clear(); + setViews(components, opts = {}) { + if (!components || !components.length) { + return Promise.resolve(); + } + + // if animate has not been set then default to false + opts.animate = opts.animate || false; + + // ensure leaving views are not cached, and should be destroyed + opts.cacheleavingView = false; + + // get the views to auto remove without having to do a transiton for each + // the last view (the currently active one) will do a normal transition out + if (this.views.length > 1) { + let autoRemoveItems = this.views.slice(0, this.views.length - 1); + for (let i = 0; i < autoRemoveItems.length; i++) { + autoRemoveItems[i].shouldDestroy = true; + autoRemoveItems[i].shouldCache = false; + autoRemoveItems[i].willUnload(); + } + } + + let componentObj = null; + let componentType = null; + let viewCtrl = null; + + // create the ViewControllers that go before the new active ViewController in the stack + // but the previous views won't should render yet + if (components.length > 1) { + let newBeforeItems = components.slice(0, components.length - 1); + for (let j = 0; j < newBeforeItems.length; j++) { + componentObj = newBeforeItems[j]; + + if (componentObj) { + + // could be an object with a componentType property, or it is a componentType + componentType = componentObj.componentType || componentObj; + + viewCtrl = new ViewController(this, componentType, componentObj.params); + viewCtrl.state = CACHED_STATE; + viewCtrl.shouldDestroy = false; + viewCtrl.shouldCache = false; + + // add the item to the stack + this.add(viewCtrl); + } + } + } + + // get the component that will become the active item + // it'll be the last one in the given components array + componentObj = components[ components.length - 1 ]; + componentType = componentObj.componentType || componentObj; + + // transition the leaving and entering + return this.push(componentType, componentObj.params, opts); } /** - * Push a new component onto the history stack. - * @return {TODO} TODO + * TODO + * @param {TODO} componentType TODO + * @param {TODO} [params={}] TODO + * @param {TODO} [opts={}] TODO + * @returns {Promise} TODO */ - push() { - return this._nav.push.apply(this._nav, arguments); + setRoot(componentType, params = {}, opts = {}) { + return this.setViews([{ + componentType, + params + }], opts); } /** - * Pop the top most (visible) component off the history stack. - * @return {TODO} TODO + * TODO + * @param {TODO} enteringView TODO + * @param {TODO} leavingView TODO + * @param {TODO} opts TODO + * @param {Function} callback TODO + * @returns {any} TODO */ - pop() { - return this._nav.pop.apply(this._nav, arguments); + transition(enteringView, leavingView, opts, callback) { + if (!enteringView || enteringView === leavingView) { + return callback(); + } + + if (opts.animate === false) { + opts.animation = 'none'; + + } else if (!opts.animation) { + opts.animation = this.config.setting('viewTransition'); + } + + opts.animate = (opts.animation !== 'none'); + + // wait for the new view to complete setup + enteringView.stage(() => { + + this.zone.runOutsideAngular(() => { + + enteringView.shouldDestroy = false; + enteringView.shouldCache = false; + enteringView.willEnter(); + leavingView.willLeave(); + + // set that the new view pushed on the stack is staged to be entering/leaving + // staged state is important for the transition to find the correct view + enteringView.state = STAGED_ENTERING_STATE; + leavingView.state = STAGED_LEAVING_STATE; + + // init the transition animation + let transAnimation = Transition.create(this, opts); + if (!opts.animate) { + // force it to not animate the elements, just apply the "to" styles + transAnimation.duration(0); + } + + let duration = transAnimation.duration(); + if (duration > 64) { + // block any clicks during the transition and provide a + // fallback to remove the clickblock if something goes wrong + this.app.setEnabled(false, duration); + } + + // start the transition + transAnimation.play().then(() => { + + // transition has completed, update each view's state + enteringView.state = ACTIVE_STATE; + leavingView.state = CACHED_STATE; + + // dispose any views that shouldn't stay around + transAnimation.dispose(); + + enteringView.didEnter(); + leavingView.didLeave(); + + // all done! + this.zone.run(() => { + this._transComplete(); + callback(); + }); + }); + + }); + + }); + } + + /** + * TODO + */ + swipeBackStart() { + if (!this.app.isEnabled() || !this.canSwipeBack()) { + return; + } + + // disables the app during the transition + this.app.setEnabled(false); + + // default the direction to "back" + let opts = { + direction: 'back' + }; + + // get the active view and set that it is staged to be leaving + // was probably the one popped from the stack + let leavingView = this.getActive() || new ViewController(); + leavingView.shouldDestroy = true; + leavingView.shouldCache = false; + leavingView.willLeave(); + leavingView.willUnload(); + + // the entering view is now the new last view + let enteringView = this.getPrevious(leavingView); + enteringView.shouldDestroy = false; + enteringView.shouldCache = false; + enteringView.willEnter(); + + // wait for the new view to complete setup + enteringView.stage(() => { + + this.zone.runOutsideAngular(() => { + // set that the new view pushed on the stack is staged to be entering/leaving + // staged state is important for the transition to find the correct view + enteringView.state = STAGED_ENTERING_STATE; + leavingView.state = STAGED_LEAVING_STATE; + + // init the swipe back transition animation + this._sbTrans = Transition.create(this, opts); + this._sbTrans.easing('linear').progressStart(); + + }); + }); + + } + + /** + * TODO + * @param {TODO} progress TODO + */ + swipeBackProgress(value) { + if (this._sbTrans) { + // continue to disable the app while actively dragging + this.app.setEnabled(false, 4000); + + // set the transition animation's progress + this._sbTrans.progress(value); + } + } + + /** + * @private + * @param {TODO} completeSwipeBack Should the swipe back complete or not. + * @param {number} rate How fast it closes + */ + swipeBackEnd(completeSwipeBack, rate) { + if (!this._sbTrans) return; + + // disables the app during the transition + this.app.setEnabled(false); + + this._sbTrans.progressEnd(completeSwipeBack, rate).then(() => { + + this.zone.run(() => { + // find the views that were entering and leaving + let enteringView = this.getStagedenteringView(); + let leavingView = this.getStagedleavingView(); + + if (enteringView && leavingView) { + // finish up the animation + + if (completeSwipeBack) { + // swipe back has completed navigating back + // update each view's state + enteringView.state = ACTIVE_STATE; + leavingView.state = CACHED_STATE; + + enteringView.didEnter(); + leavingView.didLeave(); + + if (this.router) { + // notify router of the pop state change + this.router.stateChange('pop', enteringView); + } + + } else { + // cancelled the swipe back, they didn't end up going back + // return views to their original state + leavingView.state = ACTIVE_STATE; + enteringView.state = CACHED_STATE; + + leavingView.willEnter(); + leavingView.didEnter(); + enteringView.didLeave(); + + leavingView.shouldDestroy = false; + enteringView.shouldDestroy = false; + } + } + + // empty out and dispose the swipe back transition animation + this._sbTrans && this._sbTrans.dispose(); + this._sbTrans = null; + + // all done! + this._transComplete(); + + }); + }); + + } + + _runSwipeBack() { + if (this.canSwipeBack()) { + // it is possible to swipe back + + if (this.sbGesture) { + // this is already an active gesture, don't create another one + return; + } + + let opts = { + edge: 'left', + threshold: this.sbThreshold + }; + this.sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this); + console.debug('SwipeBackGesture listen'); + this.sbGesture.listen(); + + + } else if (this.sbGesture) { + // it is not possible to swipe back and there is an + // active sbGesture, so unlisten it + console.debug('SwipeBackGesture unlisten'); + this.sbGesture.unlisten(); + this.sbGesture = null; + } + } + + /** + * TODO + * @param {TODO} val TODO + * @returns {TODO} TODO + */ + isSwipeBackEnabled(val) { + if (arguments.length) { + this.sbEnabled = !!val; + } + return this.sbEnabled; + } + + /** + * If it's possible to use swipe back or not. If it's not possible + * to go back, or swipe back is not enable then this will return false. + * If it is possible to go back, and swipe back is enabled, then this + * will return true. + * @returns {boolean} + */ + canSwipeBack() { + return (this.sbEnabled && this.canGoBack()); + } + + /** + * Returns `true` if there's a valid previous view that we can pop back to. + * Otherwise returns false. + * @returns {boolean} + */ + canGoBack() { + let activeView = this.getActive(); + if (activeView) { + return activeView.enableBack(); + } + return false; + } + + /** + * @private + */ + _transComplete() { + let destroys = []; + + this.views.forEach(view => { + if (view) { + if (view.shouldDestroy) { + destroys.push(view); + + } else if (view.state === CACHED_STATE && view.shouldCache) { + view.shouldCache = false; + } + } + }); + + destroys.forEach(view => { + this.remove(view); + view.destroy(); + }); + + // allow clicks again, but still set an enable time + // meaning nothing with this view controller can happen for XXms + this.app.setEnabled(true); + + if (this.views.length === 1) { + this.elementRef.nativeElement.classList.add('has-views'); + } + + this._runSwipeBack(); + } + + /** + * TODO + * @returns {TODO} TODO + */ + getActive() { + for (let i = 0, ii = this.views.length; i < ii; i++) { + if (this.views[i].state === ACTIVE_STATE) { + return this.views[i]; + } + } + return null; + } + + /** + * TODO + * @param {TODO} instance TODO + * @returns {TODO} TODO + */ + getByInstance(instance) { + if (instance) { + for (let i = 0, ii = this.views.length; i < ii; i++) { + if (this.views[i].instance === instance) { + return this.views[i]; + } + } + } + return null; + } + + /** + * TODO + * @param {TODO} index TODO + * @returns {TODO} TODO + */ + getByIndex(index) { + if (index < this.views.length && index > -1) { + return this.views[index]; + } + return null; + } + + /** + * TODO + * @param {TODO} view TODO + * @returns {TODO} TODO + */ + getPrevious(view) { + if (view) { + return this.views[ this.views.indexOf(view) - 1 ]; + } + return null; + } + + /** + * TODO + * @returns {TODO} TODO + */ + getStagedenteringView() { + for (let i = 0, ii = this.views.length; i < ii; i++) { + if (this.views[i].state === STAGED_ENTERING_STATE) { + return this.views[i]; + } + } + return null; + } + + /** + * TODO + * @returns {TODO} TODO + */ + getStagedleavingView() { + for (let i = 0, ii = this.views.length; i < ii; i++) { + if (this.views[i].state === STAGED_LEAVING_STATE) { + return this.views[i]; + } + } + return null; + } + + /** + * TODO + * @param {TODO} nbContainer TODO + * @returns {TODO} TODO + */ + navbarViewContainer(nbContainer) { + if (nbContainer) { + this._nbContainer = nbContainer; + } + if (this._nbContainer) { + return this._nbContainer; + } + if (this.parent) { + return this.parent.navbarViewContainer(); + } + } + + /** + * TODO + * @returns {TODO} TODO + */ + anchorElementRef() { + if (arguments.length) { + this._anchorER = arguments[0]; + } + return this._anchorER; + } + + /** + * TODO + * @returns {TODO} TODO + */ + anchorViewContainerRef() { + if (arguments.length) { + this._anchorVC = arguments[0]; + } + return this._anchorVC; + } + + /** + * TODO + * @returns {TODO} TODO + */ + childNavbar() { + if (arguments.length) { + this._childNavbar = arguments[0]; + } + return this._childNavbar; + } + + /** + * TODO + * @param {TODO} view TODO + * @returns {TODO} TODO + */ + add(view) { + view.id = this.id + '-' + (++this._ids); + this.views.push(view); + } + + /** + * TODO + * @param {TODO} viewOrIndex TODO + * @returns {TODO} TODO + */ + remove(viewOrIndex) { + util.array.remove(this.views, viewOrIndex); + } + + /** + * First view in this nav controller's stack. This would + * not return an view which is about to be destroyed. + * @returns {TODO} TODO + */ + first() { + for (let i = 0, l = this.views.length; i < l; i++) { + if (!this.views[i].shouldDestroy) { + return this.views[i]; + } + } + return null; + } + + /** + * Last view in this nav controller's stack. This would + * not return an view which is about to be destroyed. + * @returns {TODO} TODO + */ + last() { + for (let i = this.views.length - 1; i >= 0; i--) { + if (!this.views[i].shouldDestroy) { + return this.views[i]; + } + } + return null; + } + + /** + * TODO + * @param {TODO} view TODO + * @returns {TODO} TODO + */ + indexOf(view) { + return this.views.indexOf(view); + } + + /** + * Number of sibling views in the nav controller. This does + * not include views which are about to be destroyed. + * @returns {TODO} TODO + */ + length() { + let len = 0; + for (let i = 0, l = this.views.length; i < l; i++) { + if (!this.views[i].shouldDestroy) { + len++; + } + } + return len; + } + + /** + * TODO + * @returns {TODO} TODO + */ + instances() { + let instances = []; + for (let view of this.views) { + if (view.instance) { + instances.push(view.instance); + } + } + return instances; + } + + /** + * TODO + * @param {TODO} view TODO + * @returns {TODO} TODO + */ + isActive(view) { + return (view && view.state === ACTIVE_STATE); + } + + /** + * TODO + * @param {TODO} view TODO + * @returns {TODO} TODO + */ + isStagedEntering(view) { + return (view && view.state === STAGED_ENTERING_STATE); + } + + /** + * TODO + * @param {TODO} router TODO + */ + registerRouter(router) { + this.router = router; + } + } +const ACTIVE_STATE = 1; +const CACHED_STATE = 2; +const STAGED_ENTERING_STATE = 3; +const STAGED_LEAVING_STATE = 4; + +let ctrlIds = -1; + + /** * TODO */ diff --git a/ionic/components/nav/nav-router.ts b/ionic/components/nav/nav-router.ts index f76488ceb6..77bc9dcb81 100644 --- a/ionic/components/nav/nav-router.ts +++ b/ionic/components/nav/nav-router.ts @@ -29,12 +29,12 @@ export class NavRouter extends RouterOutlet { nav: Nav) { super(_elementRef, _loader, _parentRouter, nameAttr); - // Nav is Ionic's ViewController, which we injected into this class + // Nav is Ionic's NavController, which we injected into this class this.nav = nav; - // register this router with Ionic's ViewController - // Ionic's ViewController will call this NavRouter's "stateChange" - // method when the ViewController has...changed its state + // register this router with Ionic's NavController + // Ionic's NavController will call this NavRouter's "stateChange" + // method when the NavController has...changed its state nav.registerRouter(this); } @@ -55,7 +55,7 @@ export class NavRouter extends RouterOutlet { return Promise.resolve(); } - // tell the ViewController which componentType, and it's params, to navigate to + // tell the NavController which componentType, and it's params, to navigate to return this.nav.push(componentType, nextInstruction.params); } @@ -66,23 +66,23 @@ export class NavRouter extends RouterOutlet { /** * TODO * @param {TODO} type TODO - * @param {TODO} viewItem TODO + * @param {TODO} viewCtrl TODO */ - stateChange(type, viewItem) { - // stateChange is called by Ionic's ViewController + stateChange(type, viewCtrl) { + // stateChange is called by Ionic's NavController // type could be "push" or "pop" - // viewItem is Ionic's ViewItem class, which has the properties "componentType" and "params" + // viewCtrl is Ionic's ViewController class, which has the properties "componentType" and "params" // only do an update if there's an actual view change - if (!viewItem || this._activeViewId === viewItem.id) return; - this._activeViewId = viewItem.id; + if (!viewCtrl || this._activeViewId === viewCtrl.id) return; + this._activeViewId = viewCtrl.id; // get the best PathRecognizer for this view's componentType - let pathRecognizer = this.getPathRecognizerByComponent(viewItem.componentType); + let pathRecognizer = this.getPathRecognizerByComponent(viewCtrl.componentType); if (pathRecognizer) { // generate a componentInstruction from the view's PathRecognizer and params - let componentInstruction = pathRecognizer.generate(viewItem.params.data); + let componentInstruction = pathRecognizer.generate(viewCtrl.params.data); // create an Instruction from the componentInstruction let instruction = new Instruction(componentInstruction, null); diff --git a/ionic/components/nav/nav.ts b/ionic/components/nav/nav.ts index 7a9170bcb3..3f642b15a2 100644 --- a/ionic/components/nav/nav.ts +++ b/ionic/components/nav/nav.ts @@ -1,7 +1,7 @@ import {Directive, View, ElementRef, Host, Optional, forwardRef, Injector, NgZone} from 'angular2/angular2'; import {IonicComponent} from '../../config/decorators'; -import {ViewController} from '../view/view-controller'; +import {NavController} from './nav-controller'; /** * TODO @@ -19,22 +19,22 @@ import {ViewController} from '../view/view-controller'; template: '', directives: [forwardRef(() => NavPaneAnchor)] }) -export class Nav extends ViewController { +export class Nav extends NavController { /** * TODO - * @param {ViewController} hostViewCtrl TODO + * @param {NavController} hostnavCtrl TODO * @param {Injector} injector TODO * @param {ElementRef} elementRef TODO * @param {NgZone} zone TODO */ constructor( - @Optional() hostViewCtrl: ViewController, + @Optional() hostnavCtrl: NavController, injector: Injector, elementRef: ElementRef, zone: NgZone ) { - super(hostViewCtrl, injector, elementRef, zone); + super(hostnavCtrl, injector, elementRef, zone); } /** diff --git a/ionic/components/nav/pane.ts b/ionic/components/nav/pane.ts index 4de8944bce..312aa63872 100644 --- a/ionic/components/nav/pane.ts +++ b/ionic/components/nav/pane.ts @@ -2,7 +2,7 @@ import {Component, Directive, View, ElementRef, Inject, forwardRef, Injector, bi import {Ion} from '../ion'; import {IonicConfig} from '../../config/config'; -import {ViewController} from '../view/view-controller'; +import {NavController} from './nav-controller'; import {IonicComponent} from '../../config/decorators'; import {PaneAnchor, PaneContentAnchor, NavBarContainer} from './anchors'; @@ -12,14 +12,14 @@ import {PaneAnchor, PaneContentAnchor, NavBarContainer} from './anchors'; export class PaneController { /** * TODO - * @param {ViewController} viewCtrl TODO + * @param {NavController} navCtrl TODO */ - constructor(viewCtrl: ViewController) { + constructor(navCtrl: NavController) { this.panes = []; - this.viewCtrl = viewCtrl; + this.navCtrl = navCtrl; this.bindings = Injector.resolve([ - bind(ViewController).toValue(viewCtrl) + bind(NavController).toValue(navCtrl) ]); } @@ -34,7 +34,7 @@ export class PaneController { // Tabs and view's without a navbar would get a different Panes let key = itemStructure.key; - let viewCtrl = this.viewCtrl; + let navCtrl = this.navCtrl; let pane = this.panes[this.panes.length - 1]; if (pane && pane.key === key) { @@ -43,7 +43,7 @@ export class PaneController { } else { // create a new nav pane - viewCtrl.loader.loadNextToLocation(Pane, viewCtrl.anchorElementRef(), this.bindings).then((componentRef) => { + navCtrl.loader.loadNextToLocation(Pane, navCtrl.anchorElementRef(), this.bindings).then((componentRef) => { // get the pane reference pane = this.newPane; @@ -76,7 +76,7 @@ export class PaneController { // as each section is compiled and added to the Pane // the section will add a reference to itself in the Pane's sections object promises.push( - viewCtrl.loader.loadNextToLocation(SectionClass, sectionAnchorElementRef) + navCtrl.loader.loadNextToLocation(SectionClass, sectionAnchorElementRef) ); }); @@ -121,14 +121,14 @@ export class PaneController { }) export class Pane extends Ion { constructor( - @Inject(forwardRef(() => ViewController)) viewCtrl: ViewController, + @Inject(forwardRef(() => NavController)) navCtrl: NavController, elementRef: ElementRef, ionicConfig: IonicConfig ) { super(elementRef, ionicConfig); - viewCtrl.panes.add(this); + navCtrl.panes.add(this); this.totalItems = 0; - this.zIndex = ++viewCtrl.zIndexes; + this.zIndex = ++navCtrl.zIndexes; } } diff --git a/ionic/components/view/swipe-back.ts b/ionic/components/nav/swipe-back.ts similarity index 69% rename from ionic/components/view/swipe-back.ts rename to ionic/components/nav/swipe-back.ts index a10a96622e..96b59168cd 100644 --- a/ionic/components/view/swipe-back.ts +++ b/ionic/components/nav/swipe-back.ts @@ -3,27 +3,27 @@ import {SlideEdgeGesture} from 'ionic/gestures/slide-edge-gesture'; export class SwipeBackGesture extends SlideEdgeGesture { - constructor(element: Element, opts: Object = {}, viewCtrl) { + constructor(element: Element, opts: Object = {}, navCtrl) { super(element, opts); // Can check corners through use of eg 'left top' this.edges = opts.edge.split(' '); this.threshold = opts.threshold; - this.viewCtrl = viewCtrl; + this.navCtrl = navCtrl; } onSlideStart() { - this.viewCtrl.swipeBackStart(); + this.navCtrl.swipeBackStart(); } onSlide(slide, ev) { - this.viewCtrl.swipeBackProgress(slide.distance / slide.max); + this.navCtrl.swipeBackProgress(slide.distance / slide.max); } onSlideEnd(slide, ev) { let shouldComplete = (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5); // TODO: calculate a better playback rate depending on velocity and distance - this.viewCtrl.swipeBackEnd(shouldComplete, 1); + this.navCtrl.swipeBackEnd(shouldComplete, 1); } } diff --git a/ionic/components/nav/test/basic/index.ts b/ionic/components/nav/test/basic/index.ts index be6b184887..572a876891 100644 --- a/ionic/components/nav/test/basic/index.ts +++ b/ionic/components/nav/test/basic/index.ts @@ -18,7 +18,7 @@ import {NavParams, NavController} from 'ionic/ionic'; '

{{title}}

' + '

' + '

' + - '

' + + '

' + '' + '' + '' + @@ -39,12 +39,12 @@ class FirstPage { } } - setItems() { + setViews() { let items = [ ThirdPage ]; - this.nav.setItems(items); + this.nav.setViews(items); } push() { @@ -61,7 +61,7 @@ class FirstPage {

-

+

` @@ -77,13 +77,13 @@ class SecondPage { console.log('Second page params:', params); } - setItems() { + setViews() { let items = [ FirstPage, ThirdPage ]; - this.nav.setItems(items); + this.nav.setViews(items); } pop() { diff --git a/ionic/components/nav/test/routing/index.ts b/ionic/components/nav/test/routing/index.ts index 7be3fb86d3..b01264d0c4 100644 --- a/ionic/components/nav/test/routing/index.ts +++ b/ionic/components/nav/test/routing/index.ts @@ -1,13 +1,13 @@ import {RouteConfig, Location} from 'angular2/router'; -import {App, IonicView, NavParams, ViewItem} from 'ionic/ionic'; +import {App, IonicView, NavParams, ViewController} from 'ionic/ionic'; @IonicView({templateUrl: 'view1.html'}) class View1Cmp { - constructor(location: Location, viewItem: ViewItem) { + constructor(location: Location, viewCtrl: ViewController) { this.path = location.path(); - this.viewItem = viewItem; + this.viewCtrl = viewCtrl; console.log(`View1Cmp, path: ${this.path}`); } onViewDidEnter() { @@ -18,9 +18,9 @@ class View1Cmp { @IonicView({templateUrl: 'view2.html'}) class View2Cmp { - constructor(location: Location, viewItem: ViewItem) { + constructor(location: Location, viewCtrl: ViewController) { this.path = location.path(); - this.viewItem = viewItem; + this.viewCtrl = viewCtrl; console.log(`View2Cmp, path: ${this.path}`); } onViewDidEnter() { @@ -31,10 +31,10 @@ class View2Cmp { @IonicView({templateUrl: 'view3.html'}) class View3Cmp { - constructor(params: NavParams, location: Location, viewItem: ViewItem) { + constructor(params: NavParams, location: Location, viewCtrl: ViewController) { this.id = params.get('id'); this.path = location.path(); - this.viewItem = viewItem; + this.viewCtrl = viewCtrl; console.log(`View3Cmp, path: ${this.path}, param id: ${this.id}`); } onViewDidEnter() { diff --git a/ionic/components/nav/test/routing/view1.html b/ionic/components/nav/test/routing/view1.html index 78ec8a66af..983d6583b3 100644 --- a/ionic/components/nav/test/routing/view1.html +++ b/ionic/components/nav/test/routing/view1.html @@ -14,7 +14,7 @@ Location Path: {{path}}

- ViewItem Id: {{viewItem.id}} + ViewController Id: {{viewCtrl.id}}

Second View via href diff --git a/ionic/components/nav/test/routing/view2.html b/ionic/components/nav/test/routing/view2.html index e0016adaf7..f6e0b4c56c 100644 --- a/ionic/components/nav/test/routing/view2.html +++ b/ionic/components/nav/test/routing/view2.html @@ -16,7 +16,7 @@ Location Path: {{path}}

- ViewItem Id: {{viewItem.id}} + ViewController Id: {{viewCtrl.id}}

Third View via href, 12 as id param diff --git a/ionic/components/nav/test/routing/view3.html b/ionic/components/nav/test/routing/view3.html index 533913634f..3d052263cb 100644 --- a/ionic/components/nav/test/routing/view3.html +++ b/ionic/components/nav/test/routing/view3.html @@ -14,7 +14,7 @@ NavParams, id: {{id}}

- ViewItem Id: {{viewItem.id}} + ViewController Id: {{viewCtrl.id}}

Second View via href diff --git a/ionic/components/view/view-item.ts b/ionic/components/nav/view-controller.ts similarity index 90% rename from ionic/components/view/view-item.ts rename to ionic/components/nav/view-controller.ts index 0ef0eea026..a6fae1471c 100644 --- a/ionic/components/view/view-item.ts +++ b/ionic/components/nav/view-controller.ts @@ -1,15 +1,15 @@ import {Component, EventEmitter, ElementRef, bind, Injector, ComponentRef} from 'angular2/angular2'; import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector'; -import {NavParams} from '../nav/nav-controller'; +import {NavParams} from './nav-controller'; /** * TODO */ -export class ViewItem { +export class ViewController { - constructor(viewCtrl, componentType, params = {}) { - this.viewCtrl = viewCtrl; + constructor(navCtrl, componentType, params = {}) { + this.navCtrl = navCtrl; this.componentType = componentType; this.params = new NavParams(params); this.instance = null; @@ -47,9 +47,9 @@ export class ViewItem { * @returns {TODO} TODO */ stage(callback) { - let viewCtrl = this.viewCtrl; + let navCtrl = this.navCtrl; - if (this.instance || !viewCtrl) { + if (this.instance || !navCtrl) { // already compiled this view return callback(); } @@ -67,19 +67,19 @@ export class ViewItem { ionViewComponentType.token = 'ionView' + this.componentType.name; // compile the Component - viewCtrl.compiler.compileInHost(ionViewComponentType).then(hostProtoViewRef => { + navCtrl.compiler.compileInHost(ionViewComponentType).then(hostProtoViewRef => { // figure out the sturcture of this Component // does it have a navbar? Is it tabs? Should it not have a navbar or any toolbars? let itemStructure = this.sturcture = this.inspectStructure(hostProtoViewRef); - // get the appropriate Pane which this ViewItem will fit into - viewCtrl.panes.get(itemStructure, pane => { + // get the appropriate Pane which this ViewController will fit into + navCtrl.panes.get(itemStructure, pane => { this.pane = pane; - let bindings = viewCtrl.bindings.concat(Injector.resolve([ + let bindings = navCtrl.bindings.concat(Injector.resolve([ bind(NavParams).toValue(this.params), - bind(ViewItem).toValue(this) + bind(ViewController).toValue(this) ])); // add the content of the view to the content area @@ -89,8 +89,8 @@ export class ViewItem { // the same guts as DynamicComponentLoader.loadNextToLocation var hostViewRef = contentContainer.createHostView(hostProtoViewRef, -1, bindings); - var newLocation = viewCtrl.viewMngr.getHostElement(hostViewRef); - var newComponent = viewCtrl.viewMngr.getComponent(newLocation); + var newLocation = navCtrl.viewMngr.getHostElement(hostViewRef); + var newComponent = navCtrl.viewMngr.getComponent(newLocation); pane.totalItems++; var dispose = () => { @@ -108,12 +108,12 @@ export class ViewItem { this.disposals.push(dispose); var viewComponetRef = new ComponentRef(newLocation, newComponent, dispose); - // get the component's instance, and set it to the this ViewItem + // get the component's instance, and set it to the this ViewController this.setInstance(viewComponetRef.instance); this.viewElementRef(viewComponetRef.location); // // get the item container's nav bar - let navbarViewContainer = viewCtrl.navbarViewContainer(); + let navbarViewContainer = navCtrl.navbarViewContainer(); // // get the item's navbar protoview let navbarTemplateRef = this.templateRefs.navbar; @@ -186,7 +186,7 @@ export class ViewItem { }); }); - if (this.viewCtrl.childNavbar()) { + if (this.navCtrl.childNavbar()) { navbar = false; } @@ -204,8 +204,8 @@ export class ViewItem { */ enableBack() { // update if it's possible to go back from this nav item - if (this.viewCtrl) { - let previousItem = this.viewCtrl.getPrevious(this); + if (this.navCtrl) { + let previousItem = this.navCtrl.getPrevious(this); // the previous view may exist, but if it's about to be destroyed // it shouldn't be able to go back to return !!(previousItem && !previousItem.shouldDestroy); @@ -219,11 +219,10 @@ export class ViewItem { */ setInstance(instance) { this.instance = instance; - this.instance._viewItem = this; } get index() { - return (this.viewCtrl ? this.viewCtrl.indexOf(this) : -1); + return (this.navCtrl ? this.navCtrl.indexOf(this) : -1); } isRoot() { diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts index a872b07d05..c4f4ae99e8 100644 --- a/ionic/components/tabs/tab.ts +++ b/ionic/components/tabs/tab.ts @@ -1,7 +1,7 @@ import {Directive, Component, View, Host, ElementRef, forwardRef, Injector, NgZone} from 'angular2/angular2'; -import {ViewController} from '../view/view-controller'; -import {ViewItem} from '../view/view-item'; +import {NavController} from '../nav/nav-controller'; +import {ViewController} from '../nav/view-controller'; import {Tabs} from './tabs'; @@ -35,7 +35,7 @@ import {Tabs} from './tabs'; template: '', directives: [forwardRef(() => TabPaneAnchor)] }) -export class Tab extends ViewController { +export class Tab extends NavController { /** * TODO @@ -51,32 +51,32 @@ export class Tab extends ViewController { zone: NgZone ) { // A Tab is both a container of many views, and is a view itself. - // A Tab is one ViewItem within it's Host Tabs (which extends ViewController) - // A Tab is a ViewController for its child ViewItems + // A Tab is one ViewController within it's Host Tabs (which extends NavController) + // A Tab is a NavController for its child ViewControllers super(tabs, injector, elementRef, zone); this.tabs = tabs; this.childNavbar(true); - let item = this.item = new ViewItem(tabs.Host); - item.setInstance(this); - item.viewElementRef(elementRef); + let viewCtrl = this.viewCtrl = new ViewController(tabs.Host); + viewCtrl.setInstance(this); + viewCtrl.viewElementRef(elementRef); tabs.addTab(this); - this.navbarView = item.navbarView = () => { - let activeItem = this.getActive(); - return activeItem && activeItem.navbarView(); + this.navbarView = viewCtrl.navbarView = () => { + let activeView = this.getActive(); + return activeView && activeView.navbarView(); }; - item.enableBack = () => { - // override ViewItem's enableBack(), should use the + viewCtrl.enableBack = () => { + // override ViewController's enableBack(), should use the // active child nav item's enableBack() instead - let activeItem = this.getActive(); - return (activeItem && activeItem.enableBack()); + let activeView = this.getActive(); + return (activeView && activeView.enableBack()); }; - this.panelId = 'tab-panel-' + item.id; - this.labeledBy = 'tab-button-' + item.id; + this.panelId = 'tab-panel-' + viewCtrl.id; + this.labeledBy = 'tab-button-' + viewCtrl.id; } onInit() { @@ -118,11 +118,11 @@ export class Tab extends ViewController { } get isSelected() { - return this.tabs.isActive(this.item); + return this.tabs.isActive(this.viewCtrl); } get isNotSelected() { - return !this.tabs.isActive(this.item); + return !this.tabs.isActive(this.viewCtrl); } } diff --git a/ionic/components/tabs/tabs.ts b/ionic/components/tabs/tabs.ts index 3dfb8af5d3..346512ec2e 100644 --- a/ionic/components/tabs/tabs.ts +++ b/ionic/components/tabs/tabs.ts @@ -1,8 +1,8 @@ import {Component, Directive, View, Injector, NgFor, ElementRef, Optional, Host, forwardRef, NgZone} from 'angular2/angular2'; import {IonicApp} from '../app/app'; -import {ViewController} from '../view/view-controller'; -import {ViewItem} from '../view/view-item'; +import {NavController} from '../nav/nav-controller'; +import {ViewController} from '../nav/view-controller'; import {Icon} from '../icon/icon'; import {IonicComponent, IonicView} from '../../config/decorators'; @@ -50,41 +50,41 @@ import {IonicComponent, IonicView} from '../../config/decorators'; '', directives: [forwardRef(() => TabButton)] }) -export class Tabs extends ViewController { +export class Tabs extends NavController { /** * TODO */ constructor( - @Optional() hostViewCtrl: ViewController, - @Optional() viewItem: ViewItem, + @Optional() hostNavCtrl: NavController, + @Optional() viewCtrl: ViewController, app: IonicApp, injector: Injector, elementRef: ElementRef, zone: NgZone ) { - super(hostViewCtrl, injector, elementRef, zone); + super(hostNavCtrl, injector, elementRef, zone); this.app = app; - // Tabs may also be an actual ViewItem which was navigated to - // if Tabs is static and not navigated to within a ViewController - // then skip this and don't treat it as it's own ViewItem - if (viewItem) { - this.item = viewItem; + // Tabs may also be an actual ViewController which was navigated to + // if Tabs is static and not navigated to within a NavController + // then skip this and don't treat it as it's own ViewController + if (viewCtrl) { + this.viewCtrl = viewCtrl; - // special overrides for the Tabs ViewItem - // the Tabs ViewItem does not have it's own navbar + // special overrides for the Tabs ViewController + // the Tabs ViewController does not have it's own navbar // so find the navbar it should use within it's active Tab - viewItem.navbarView = () => { + viewCtrl.navbarView = () => { let activeTab = this.getActive(); if (activeTab && activeTab.instance) { return activeTab.instance.navbarView(); } }; - // a Tabs ViewItem should not have a back button + // a Tabs ViewController should not have a back button // enableBack back button will later be determined - // by the active ViewItem that has a navbar - viewItem.enableBack = () => { + // by the active ViewController that has a navbar + ViewController.enableBack = () => { return false; }; } @@ -96,14 +96,14 @@ export class Tabs extends ViewController { * @param {Tab} tab TODO */ addTab(tab) { - // tab.item refers to the ViewItem of the individual Tab being added to Tabs (ViewController) - // this.item refers to the ViewItem instsance on Tabs - this.add(tab.item); + // tab.viewCtrl refers to the ViewController of the individual Tab being added to Tabs (NavController) + // this.viewCtrl refers to the ViewController instsance on Tabs + this.add(tab.viewCtrl); if (this.length() === 1) { // this was the first tab added, queue this one to be loaded and selected let promise = tab.queueInitial(); - this.item && this.item.addPromise(promise); + this.viewCtrl && this.viewCtrl.addPromise(promise); } } @@ -113,28 +113,28 @@ export class Tabs extends ViewController { * @returns {TODO} TODO */ select(tab) { - let enteringItem = null; + let enteringView = null; if (typeof tab === 'number') { - enteringItem = this.getByIndex(tab); + enteringView = this.getByIndex(tab); } else { - enteringItem = this.getByInstance(tab) + enteringView = this.getByInstance(tab) } - if (!enteringItem || !enteringItem.instance || !this.app.isEnabled()) { + if (!enteringView || !enteringView.instance || !this.app.isEnabled()) { return Promise.reject(); } return new Promise(resolve => { - enteringItem.instance.load(() => { + enteringView.instance.load(() => { let opts = { animate: false }; - let leavingItem = this.getActive() || new ViewItem(); - leavingItem.shouldDestroy = false; - leavingItem.shouldCache = true; + let leavingView = this.getActive() || new ViewController(); + leavingView.shouldDestroy = false; + leavingView.shouldCache = true; - this.transition(enteringItem, leavingItem, opts, () => { + this.transition(enteringView, leavingView, opts, () => { resolve(); }); }); @@ -171,7 +171,7 @@ class TabButton { } onInit() { - let id = this.tab.item.id; + let id = this.tab.viewCtrl.id; this.btnId = 'tab-button-' + id; this.panelId = 'tab-panel-' + id; diff --git a/ionic/components/view/view-controller.ts b/ionic/components/view/view-controller.ts deleted file mode 100644 index f68ffa257d..0000000000 --- a/ionic/components/view/view-controller.ts +++ /dev/null @@ -1,780 +0,0 @@ -import {Compiler, ElementRef, Injector, bind, NgZone} from 'angular2/angular2'; -import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader'; -import {AppViewManager} from 'angular2/src/core/compiler/view_manager'; - -import {Ion} from '../ion'; -import {IonicConfig} from '../../config/config'; -import {IonicApp} from '../app/app'; -import {ViewItem} from './view-item'; -import {NavController} from '../nav/nav-controller'; -import {PaneController} from '../nav/pane'; -import {Transition} from '../../transitions/transition'; -import {SwipeBackGesture} from './swipe-back'; -import * as util from 'ionic/util'; - -/** - * TODO - */ -export class ViewController extends Ion { - - constructor( - parentViewCtrl: ViewController, - injector: Injector, - elementRef: ElementRef, - zone: NgZone - ) { - let config = injector.get(IonicConfig); - super(elementRef, config); - - this.parent = parentViewCtrl; - - this.compiler = injector.get(Compiler); - this.loader = injector.get(DynamicComponentLoader); - this.viewMngr = injector.get(AppViewManager); - this.app = injector.get(IonicApp); - this.config = config; - this.zone = zone; - - this.items = []; - this.panes = new PaneController(this); - - this._sbTrans = null; - this.sbEnabled = config.setting('swipeBackEnabled') || false; - this.sbThreshold = config.setting('swipeBackThreshold') || 40 - - this.id = ++ctrlIds; - this._ids = -1; - this.zIndexes = -1; - - // build a new injector for child ViewItems to use - this.bindings = Injector.resolve([ - bind(ViewController).toValue(this), - bind(NavController).toValue(new NavController(this)) - ]); - } - - /** - * TODO - * @param {TODO} componentType TODO - * @param {TODO} [params={}] TODO - * @param {TODO} [opts={}] TODO - * @returns {Promise} TODO - */ - push(componentType, params = {}, opts = {}) { - if (!componentType) { - return Promise.reject(); - } - if (typeof componentType !== 'function') { - throw 'Loading component must be a component class, not "' + componentType.toString() + '"'; - } - - let resolve; - let promise = new Promise(res => { resolve = res; }); - - // do not animate if this is the first in the stack - if (!this.items.length) { - opts.animation = 'none'; - } - - // default the direction to "forward" - opts.direction = opts.direction || 'forward'; - - // the active item is going to be the leaving one (if one exists) - let leavingItem = this.getActive() || new ViewItem(); - leavingItem.shouldCache = (util.isBoolean(opts.cacheLeavingItem) ? opts.cacheLeavingItem : true); - leavingItem.shouldDestroy = !leavingItem.shouldCache; - if (leavingItem.shouldDestroy) { - leavingItem.willUnload(); - } - - // create a new ViewItem - let enteringItem = new ViewItem(this, componentType, params); - - // add the item to the stack - this.add(enteringItem); - - if (this.router) { - // notify router of the state change - this.router.stateChange('push', enteringItem, params); - } - - // start the transition - this.transition(enteringItem, leavingItem, opts, () => { - resolve(); - }); - - return promise; - } - - /** - * TODO - * @param {TODO} [opts={}] TODO - * @returns {Promise} TODO - */ - pop(opts = {}) { - if (!this.canGoBack()) { - return Promise.reject(); - } - - let resolve; - let promise = new Promise(res => { resolve = res; }); - - // default the direction to "back" - opts.direction = opts.direction || 'back'; - - // get the active item and set that it is staged to be leaving - // was probably the one popped from the stack - let leavingItem = this.getActive() || new ViewItem(); - leavingItem.shouldCache = (util.isBoolean(opts.cacheLeavingItem) ? opts.cacheLeavingItem : false); - leavingItem.shouldDestroy = !leavingItem.shouldCache; - if (leavingItem.shouldDestroy) { - leavingItem.willUnload(); - } - - // the entering item is now the new last item - // Note: we might not have an entering item if this is the - // only item on the history stack. - let enteringItem = this.getPrevious(leavingItem); - if (enteringItem) { - if (this.router) { - // notify router of the state change - this.router.stateChange('pop', enteringItem); - } - - // start the transition - this.transition(enteringItem, leavingItem, opts, () => { - // transition completed, destroy the leaving item - resolve(); - }); - - } else { - this._transComplete(); - resolve(); - } - - return promise; - } - - /** - * Set the item stack to reflect the given component classes. - * @param {TODO} components TODO - * @param {TODO} [opts={}] TODO - * @returns {Promise} TODO - */ - setItems(components, opts = {}) { - if (!components || !components.length) { - return Promise.resolve(); - } - - // if animate has not been set then default to false - opts.animate = opts.animate || false; - - // ensure leaving items are not cached, and should be destroyed - opts.cacheLeavingItem = false; - - // get the items to auto remove without having to do a transiton for each - // the last item (the currently active one) will do a normal transition out - if (this.items.length > 1) { - let autoRemoveItems = this.items.slice(0, this.items.length - 1); - for (let i = 0; i < autoRemoveItems.length; i++) { - autoRemoveItems[i].shouldDestroy = true; - autoRemoveItems[i].shouldCache = false; - autoRemoveItems[i].willUnload(); - } - } - - let componentObj = null; - let componentType = null; - let viewItem = null; - - // create the ViewItems that go before the new active ViewItem in the stack - // but the previous views won't should render yet - if (components.length > 1) { - let newBeforeItems = components.slice(0, components.length - 1); - for (let j = 0; j < newBeforeItems.length; j++) { - componentObj = newBeforeItems[j]; - - if (componentObj) { - - // could be an object with a componentType property, or it is a componentType - componentType = componentObj.componentType || componentObj; - - viewItem = new ViewItem(this, componentType, componentObj.params); - viewItem.state = CACHED_STATE; - viewItem.shouldDestroy = false; - viewItem.shouldCache = false; - - // add the item to the stack - this.add(viewItem); - } - } - } - - // get the component that will become the active item - // it'll be the last one in the given components array - componentObj = components[ components.length - 1 ]; - componentType = componentObj.componentType || componentObj; - - // transition the leaving and entering - return this.push(componentType, componentObj.params, opts); - } - - /** - * TODO - * @param {TODO} componentType TODO - * @param {TODO} [params={}] TODO - * @param {TODO} [opts={}] TODO - * @returns {Promise} TODO - */ - setRoot(componentType, params = {}, opts = {}) { - return this.setItems([{ - componentType, - params - }], opts); - } - - /** - * TODO - * @param {TODO} enteringItem TODO - * @param {TODO} leavingItem TODO - * @param {TODO} opts TODO - * @param {Function} callback TODO - * @returns {any} TODO - */ - transition(enteringItem, leavingItem, opts, callback) { - if (!enteringItem || enteringItem === leavingItem) { - return callback(); - } - - if (opts.animate === false) { - opts.animation = 'none'; - - } else if (!opts.animation) { - opts.animation = this.config.setting('viewTransition'); - } - - opts.animate = (opts.animation !== 'none'); - - // wait for the new item to complete setup - enteringItem.stage(() => { - - this.zone.runOutsideAngular(() => { - - enteringItem.shouldDestroy = false; - enteringItem.shouldCache = false; - enteringItem.willEnter(); - leavingItem.willLeave(); - - // set that the new item pushed on the stack is staged to be entering/leaving - // staged state is important for the transition to find the correct item - enteringItem.state = STAGED_ENTERING_STATE; - leavingItem.state = STAGED_LEAVING_STATE; - - // init the transition animation - let transAnimation = Transition.create(this, opts); - if (!opts.animate) { - // force it to not animate the elements, just apply the "to" styles - transAnimation.duration(0); - } - - let duration = transAnimation.duration(); - if (duration > 64) { - // block any clicks during the transition and provide a - // fallback to remove the clickblock if something goes wrong - this.app.setEnabled(false, duration); - } - - // start the transition - transAnimation.play().then(() => { - - // transition has completed, update each item's state - enteringItem.state = ACTIVE_STATE; - leavingItem.state = CACHED_STATE; - - // dispose any items that shouldn't stay around - transAnimation.dispose(); - - enteringItem.didEnter(); - leavingItem.didLeave(); - - // all done! - this.zone.run(() => { - this._transComplete(); - callback(); - }); - }); - - }); - - }); - - } - - /** - * TODO - */ - swipeBackStart() { - if (!this.app.isEnabled() || !this.canSwipeBack()) { - return; - } - - // disables the app during the transition - this.app.setEnabled(false); - - // default the direction to "back" - let opts = { - direction: 'back' - }; - - // get the active item and set that it is staged to be leaving - // was probably the one popped from the stack - let leavingItem = this.getActive() || new ViewItem(); - leavingItem.shouldDestroy = true; - leavingItem.shouldCache = false; - leavingItem.willLeave(); - leavingItem.willUnload(); - - // the entering item is now the new last item - let enteringItem = this.getPrevious(leavingItem); - enteringItem.shouldDestroy = false; - enteringItem.shouldCache = false; - enteringItem.willEnter(); - - // wait for the new item to complete setup - enteringItem.stage(() => { - - this.zone.runOutsideAngular(() => { - // set that the new item pushed on the stack is staged to be entering/leaving - // staged state is important for the transition to find the correct item - enteringItem.state = STAGED_ENTERING_STATE; - leavingItem.state = STAGED_LEAVING_STATE; - - // init the swipe back transition animation - this._sbTrans = Transition.create(this, opts); - this._sbTrans.easing('linear').progressStart(); - - }); - }); - - } - - /** - * TODO - * @param {TODO} progress TODO - */ - swipeBackProgress(value) { - if (this._sbTrans) { - // continue to disable the app while actively dragging - this.app.setEnabled(false, 4000); - - // set the transition animation's progress - this._sbTrans.progress(value); - } - } - - /** - * @private - * @param {TODO} completeSwipeBack Should the swipe back complete or not. - * @param {number} rate How fast it closes - */ - swipeBackEnd(completeSwipeBack, rate) { - if (!this._sbTrans) return; - - // disables the app during the transition - this.app.setEnabled(false); - - this._sbTrans.progressEnd(completeSwipeBack, rate).then(() => { - - this.zone.run(() => { - // find the items that were entering and leaving - let enteringItem = this.getStagedEnteringItem(); - let leavingItem = this.getStagedLeavingItem(); - - if (enteringItem && leavingItem) { - // finish up the animation - - if (completeSwipeBack) { - // swipe back has completed navigating back - // update each item's state - enteringItem.state = ACTIVE_STATE; - leavingItem.state = CACHED_STATE; - - enteringItem.didEnter(); - leavingItem.didLeave(); - - if (this.router) { - // notify router of the pop state change - this.router.stateChange('pop', enteringItem); - } - - } else { - // cancelled the swipe back, they didn't end up going back - // return items to their original state - leavingItem.state = ACTIVE_STATE; - enteringItem.state = CACHED_STATE; - - leavingItem.willEnter(); - leavingItem.didEnter(); - enteringItem.didLeave(); - - leavingItem.shouldDestroy = false; - enteringItem.shouldDestroy = false; - } - } - - // empty out and dispose the swipe back transition animation - this._sbTrans && this._sbTrans.dispose(); - this._sbTrans = null; - - // all done! - this._transComplete(); - - }); - }); - - } - - _runSwipeBack() { - if (this.canSwipeBack()) { - // it is possible to swipe back - - if (this.sbGesture) { - // this is already an active gesture, don't create another one - return; - } - - let opts = { - edge: 'left', - threshold: this.sbThreshold - }; - this.sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this); - console.debug('SwipeBackGesture listen'); - this.sbGesture.listen(); - - - } else if (this.sbGesture) { - // it is not possible to swipe back and there is an - // active sbGesture, so unlisten it - console.debug('SwipeBackGesture unlisten'); - this.sbGesture.unlisten(); - this.sbGesture = null; - } - } - - /** - * TODO - * @param {TODO} val TODO - * @returns {TODO} TODO - */ - isSwipeBackEnabled(val) { - if (arguments.length) { - this.sbEnabled = !!val; - } - return this.sbEnabled; - } - - /** - * If it's possible to use swipe back or not. If it's not possible - * to go back, or swipe back is not enable then this will return false. - * If it is possible to go back, and swipe back is enabled, then this - * will return true. - * @returns {boolean} - */ - canSwipeBack() { - return (this.sbEnabled && this.canGoBack()); - } - - /** - * Returns `true` if there's a valid previous view that we can pop back to. - * Otherwise returns false. - * @returns {boolean} - */ - canGoBack() { - let activeItem = this.getActive(); - if (activeItem) { - return activeItem.enableBack(); - } - return false; - } - - /** - * @private - */ - _transComplete() { - let destroys = []; - - this.items.forEach(item => { - if (item) { - if (item.shouldDestroy) { - destroys.push(item); - - } else if (item.state === CACHED_STATE && item.shouldCache) { - item.shouldCache = false; - } - } - }); - - destroys.forEach(item => { - this.remove(item); - item.destroy(); - }); - - // allow clicks again, but still set an enable time - // meaning nothing with this view controller can happen for XXms - this.app.setEnabled(true); - - if (this.items.length === 1) { - this.elementRef.nativeElement.classList.add('has-views'); - } - - this._runSwipeBack(); - } - - /** - * TODO - * @returns {TODO} TODO - */ - getActive() { - for (let i = 0, ii = this.items.length; i < ii; i++) { - if (this.items[i].state === ACTIVE_STATE) { - return this.items[i]; - } - } - return null; - } - - /** - * TODO - * @param {TODO} instance TODO - * @returns {TODO} TODO - */ - getByInstance(instance) { - if (instance) { - for (let i = 0, ii = this.items.length; i < ii; i++) { - if (this.items[i].instance === instance) { - return this.items[i]; - } - } - } - return null; - } - - /** - * TODO - * @param {TODO} index TODO - * @returns {TODO} TODO - */ - getByIndex(index) { - if (index < this.items.length && index > -1) { - return this.items[index]; - } - return null; - } - - /** - * TODO - * @param {TODO} item TODO - * @returns {TODO} TODO - */ - getPrevious(item) { - if (item) { - return this.items[ this.items.indexOf(item) - 1 ]; - } - return null; - } - - /** - * TODO - * @returns {TODO} TODO - */ - getStagedEnteringItem() { - for (let i = 0, ii = this.items.length; i < ii; i++) { - if (this.items[i].state === STAGED_ENTERING_STATE) { - return this.items[i]; - } - } - return null; - } - - /** - * TODO - * @returns {TODO} TODO - */ - getStagedLeavingItem() { - for (let i = 0, ii = this.items.length; i < ii; i++) { - if (this.items[i].state === STAGED_LEAVING_STATE) { - return this.items[i]; - } - } - return null; - } - - /** - * TODO - * @param {TODO} nbContainer TODO - * @returns {TODO} TODO - */ - navbarViewContainer(nbContainer) { - if (nbContainer) { - this._nbContainer = nbContainer; - } - if (this._nbContainer) { - return this._nbContainer; - } - if (this.parent) { - return this.parent.navbarViewContainer(); - } - } - - /** - * TODO - * @returns {TODO} TODO - */ - anchorElementRef() { - if (arguments.length) { - this._anchorER = arguments[0]; - } - return this._anchorER; - } - - /** - * TODO - * @returns {TODO} TODO - */ - anchorViewContainerRef() { - if (arguments.length) { - this._anchorVC = arguments[0]; - } - return this._anchorVC; - } - - /** - * TODO - * @returns {TODO} TODO - */ - childNavbar() { - if (arguments.length) { - this._childNavbar = arguments[0]; - } - return this._childNavbar; - } - - /** - * TODO - * @param {TODO} item TODO - * @returns {TODO} TODO - */ - add(item) { - item.id = this.id + '-' + (++this._ids); - this.items.push(item); - } - - /** - * TODO - * @param {TODO} itemOrIndex TODO - * @returns {TODO} TODO - */ - remove(itemOrIndex) { - util.array.remove(this.items, itemOrIndex); - } - - /** - * First view item in this view controller's stack. This would - * not return an item which is about to be destroyed. - * @returns {TODO} TODO - */ - first() { - for (let i = 0, l = this.items.length; i < l; i++) { - if (!this.items[i].shouldDestroy) { - return this.items[i]; - } - } - return null; - } - - /** - * Last view item in this view controller's stack. This would - * not return an item which is about to be destroyed. - * @returns {TODO} TODO - */ - last() { - for (let i = this.items.length - 1; i >= 0; i--) { - if (!this.items[i].shouldDestroy) { - return this.items[i]; - } - } - return null; - } - - /** - * TODO - * @param {TODO} item TODO - * @returns {TODO} TODO - */ - indexOf(item) { - return this.items.indexOf(item); - } - - /** - * Number of sibling view items in the view controller. This does - * not include items which are about to be destroyed. - * @returns {TODO} TODO - */ - length() { - let len = 0; - for (let i = 0, l = this.items.length; i < l; i++) { - if (!this.items[i].shouldDestroy) { - len++; - } - } - return len; - } - - /** - * TODO - * @returns {TODO} TODO - */ - instances() { - let instances = []; - for (let item of this.items) { - if (item.instance) { - instances.push(item.instance); - } - } - return instances; - } - - /** - * TODO - * @param {TODO} item TODO - * @returns {TODO} TODO - */ - isActive(item) { - return (item && item.state === ACTIVE_STATE); - } - - /** - * TODO - * @param {TODO} item TODO - * @returns {TODO} TODO - */ - isStagedEntering(item) { - return (item && item.state === STAGED_ENTERING_STATE); - } - - /** - * TODO - * @param {TODO} router TODO - */ - registerRouter(router) { - this.router = router; - } - -} - -const ACTIVE_STATE = 1; -const CACHED_STATE = 2; -const STAGED_ENTERING_STATE = 3; -const STAGED_LEAVING_STATE = 4; - -let ctrlIds = -1; diff --git a/ionic/components/view/view.scss b/ionic/components/view/view.scss deleted file mode 100644 index 042a49e86a..0000000000 --- a/ionic/components/view/view.scss +++ /dev/null @@ -1,17 +0,0 @@ - -// View -// -------------------------------------------------- - -ion-view { - display: flex; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - flex-direction: column; - - background-color: white; - - transform: translateZ(0px); -} diff --git a/ionic/ionic.core.scss b/ionic/ionic.core.scss index 792960d6ab..612c128cdb 100644 --- a/ionic/ionic.core.scss +++ b/ionic/ionic.core.scss @@ -47,8 +47,7 @@ "components/search-bar/search-bar", "components/segment/segment", "components/switch/switch", - "components/tabs/tabs", - "components/view/view"; + "components/tabs/tabs"; // Ionicons diff --git a/ionic/transitions/transition.ts b/ionic/transitions/transition.ts index 728b0a56db..19fb51a977 100644 --- a/ionic/transitions/transition.ts +++ b/ionic/transitions/transition.ts @@ -14,61 +14,61 @@ export class Transition extends Animation { super(); // get the entering and leaving items - let enteringItem = this.entering = nav.getStagedEnteringItem(); - let leavingItem = this.leaving = nav.getStagedLeavingItem(); + let enteringView = this.entering = nav.getStagedenteringView(); + let leavingView = this.leaving = nav.getStagedleavingView(); // create animation for the entering item's "ion-view" element - this.enteringView = new Animation(enteringItem.viewElementRef()); + this.enteringView = new Animation(enteringView.viewElementRef()); this.enteringView.before.addClass(SHOW_VIEW_CSS); this.enteringView.onPlay(() => { - enteringItem.postRender(); + enteringView.postRender(); }); this.add(this.enteringView); if (opts.navbar !== false) { - let enteringNavbar = this.enteringNavbar = new Animation(enteringItem.navbarRef()); + let enteringNavbar = this.enteringNavbar = new Animation(enteringView.navbarRef()); enteringNavbar.before.addClass(SHOW_NAVBAR_CSS); - if (enteringItem.enableBack()) { + if (enteringView.enableBack()) { // only animate in the back button if the entering view has it enabled - let enteringBackButton = this.enteringBackButton = new Animation(enteringItem.backBtnRef()); + let enteringBackButton = this.enteringBackButton = new Animation(enteringView.backBtnRef()); enteringBackButton .before.addClass(SHOW_BACK_BUTTON) .fadeIn(); enteringNavbar.add(enteringBackButton); } - this.enteringTitle = new Animation(enteringItem.titleRef()); + this.enteringTitle = new Animation(enteringView.titleRef()); enteringNavbar.add(this.enteringTitle); this.add(enteringNavbar); - this.enteringNavbarItems = new Animation(enteringItem.navbarItemRefs()); + this.enteringNavbarItems = new Animation(enteringView.navbarItemRefs()); this.enteringNavbarItems.fadeIn(); enteringNavbar.add(this.enteringNavbarItems); } - if (leavingItem) { + if (leavingView) { // setup the leaving item if one exists (initial viewing wouldn't have a leaving item) - this.leavingView = new Animation(leavingItem.viewElementRef()); + this.leavingView = new Animation(leavingView.viewElementRef()); this.leavingView.after.removeClass(SHOW_VIEW_CSS); - let leavingNavbar = this.leavingNavbar = new Animation(leavingItem.navbarRef()); + let leavingNavbar = this.leavingNavbar = new Animation(leavingView.navbarRef()); leavingNavbar.after.removeClass(SHOW_NAVBAR_CSS); - let leavingBackButton = this.leavingBackButton = new Animation(leavingItem.backBtnRef()); + let leavingBackButton = this.leavingBackButton = new Animation(leavingView.backBtnRef()); leavingBackButton .after.removeClass(SHOW_BACK_BUTTON) .fadeOut(); leavingNavbar.add(leavingBackButton); - this.leavingTitle = new Animation(leavingItem.titleRef()); + this.leavingTitle = new Animation(leavingView.titleRef()); leavingNavbar.add(this.leavingTitle); - this.leavingNavbarItems = new Animation(leavingItem.navbarItemRefs()); + this.leavingNavbarItems = new Animation(leavingView.navbarItemRefs()); this.leavingNavbarItems.fadeOut(); leavingNavbar.add(this.leavingNavbarItems);