refactor: improve tree shaking abilities

Internal refactor completed in order to improve tree shaking and dead
code removal. The public API, with an exception to ion-slides, has
stayed the same. However, internally many changes were required so
bundlers could better exclude modules which should not be bundled.
Ultimately most changes resorted to removing references to `window` or
`document`, or a module that referenced one of those.

BREAKING CHANGES

ion-slides was refactored to remove the external dependencies, and
rewritten in TypeScript/ES6 modules to again improve tree shaking
abilities.
This commit is contained in:
Adam Bradley
2017-01-09 09:51:39 -06:00
parent 13cf6a6cb7
commit 7000b1b173
191 changed files with 9401 additions and 13664 deletions

View File

@ -7,17 +7,18 @@ import { convertToView, convertToViews, NavOptions, DIRECTION_BACK, DIRECTION_FO
TransitionResolveFn, TransitionInstruction, ViewState } from './nav-util';
import { setZIndex } from './nav-util';
import { DeepLinker } from './deep-linker';
import { DomController } from '../platform/dom-controller';
import { GestureController } from '../gestures/gesture-controller';
import { isBlank, isNumber, isPresent, assert, removeArrayItem } from '../util/util';
import { isViewController, ViewController } from './view-controller';
import { Ion } from '../components/ion';
import { Keyboard } from '../util/keyboard';
import { Keyboard } from '../platform/keyboard';
import { NavController } from './nav-controller';
import { NavParams } from './nav-params';
import { Platform } from '../platform/platform';
import { SwipeBackGesture } from './swipe-back';
import { Transition } from '../transitions/transition';
import { TransitionController } from '../transitions/transition-controller';
import { DomController } from '../util/dom-controller';
/**
* @private
@ -52,6 +53,7 @@ export class NavControllerBase extends Ion implements NavController {
public parent: any,
public _app: App,
public config: Config,
public plt: Platform,
public _keyboard: Keyboard,
elementRef: ElementRef,
public _zone: NgZone,
@ -566,7 +568,7 @@ export class NavControllerBase extends Ion implements NavController {
direction: opts.direction,
duration: (opts.animate === false ? 0 : opts.duration),
easing: opts.easing,
isRTL: this._config.platform.isRTL(),
isRTL: this._config.plt.isRTL(),
ev: opts.ev,
};
@ -961,7 +963,7 @@ export class NavControllerBase extends Ion implements NavController {
_swipeBackCheck() {
if (this.canSwipeBack()) {
if (!this._sbGesture) {
this._sbGesture = new SwipeBackGesture(this, this._gestureCtrl, this._domCtrl);
this._sbGesture = new SwipeBackGesture(this.plt, this, this._gestureCtrl, this._domCtrl);
}
this._sbGesture.listen();

View File

@ -254,16 +254,16 @@ import { ViewController } from './view-controller';
* }
* ```
*
* | Page Event | Returns | Description |
* |---------------------|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
* | `ionViewDidLoad` | void | Runs when the page has loaded. This event only happens once per page being created. If a page leaves but is cached, then this event will not fire again on a subsequent viewing. The `ionViewDidLoad` event is good place to put your setup code for the page. |
* | `ionViewWillEnter` | void | Runs when the page is about to enter and become the active page. |
* | `ionViewDidEnter` | void | Runs when the page has fully entered and is now the active page. This event will fire, whether it was the first load or a cached page. |
* | `ionViewWillLeave` | void | Runs when the page is about to leave and no longer be the active page. |
* | `ionViewDidLeave` | void | Runs when the page has finished leaving and is no longer the active page. |
* | `ionViewWillUnload` | void | Runs when the page is about to be destroyed and have its elements removed. |
* | `ionViewCanEnter` | boolean &#124; Promise\<void\> | Runs before the view can enter. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can enter |
* | `ionViewCanLeave` | boolean &#124; Promise\<void\> | Runs before the view can leave. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can leave |
* | Page Event | Returns | Description |
* |---------------------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
* | `ionViewDidLoad` | void | Runs when the page has loaded. This event only happens once per page being created. If a page leaves but is cached, then this event will not fire again on a subsequent viewing. The `ionViewDidLoad` event is good place to put your setup code for the page. |
* | `ionViewWillEnter` | void | Runs when the page is about to enter and become the active page. |
* | `ionViewDidEnter` | void | Runs when the page has fully entered and is now the active page. This event will fire, whether it was the first load or a cached page. |
* | `ionViewWillLeave` | void | Runs when the page is about to leave and no longer be the active page. |
* | `ionViewDidLeave` | void | Runs when the page has finished leaving and is no longer the active page. |
* | `ionViewWillUnload` | void | Runs when the page is about to be destroyed and have its elements removed. |
* | `ionViewCanEnter` | boolean/Promise&lt;void&gt; | Runs before the view can enter. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can enter |
* | `ionViewCanLeave` | boolean/Promise&lt;void&gt; | Runs before the view can leave. This can be used as a sort of "guard" in authenticated views where you need to check permissions before the view can leave |
*
*
* ## Nav Guards
@ -514,7 +514,7 @@ export abstract class NavController {
* by passing options to the navigation controller.You can also pass any
* navigation params to the individual pages in the array.
*
* @param {array<Page>} pages An arry of page components and their params to load in the stack.
* @param {array} pages An array of objects, each with a `page` and optionally `params` property to load in the stack.
* @param {object} [opts={}] Nav options to go with this transition.
* @returns {Promise} Returns a promise which is resolved when the transition has completed.
*/

View File

@ -1,9 +1,10 @@
import { swipeShouldReset } from '../util/util';
import { DomController } from '../platform/dom-controller';
import { GestureController, GesturePriority, GESTURE_GO_BACK_SWIPE } from '../gestures/gesture-controller';
import { NavControllerBase } from './nav-controller-base';
import { Platform } from '../platform/platform';
import { SlideData } from '../gestures/slide-gesture';
import { SlideEdgeGesture } from '../gestures/slide-edge-gesture';
import { DomController } from '../util/dom-controller';
/**
* @private
@ -11,11 +12,12 @@ import { DomController } from '../util/dom-controller';
export class SwipeBackGesture extends SlideEdgeGesture {
constructor(
plt: Platform,
private _nav: NavControllerBase,
gestureCtlr: GestureController,
domCtrl: DomController,
) {
super(document.body, {
super(plt, plt.doc().body, {
direction: 'x',
edge: 'left',
maxEdgeStart: 75,

View File

@ -948,86 +948,6 @@ describe('NavController', () => {
});
// describe('_cleanup', () => {
// it('should destroy views that are inactive after the active view', () => {
// let view1 = new ViewController(Page1);
// view1.state = STATE_INACTIVE;
// let view2 = new ViewController(Page2);
// view2.state = STATE_ACTIVE;
// let view3 = new ViewController(Page3);
// view3.state = STATE_INACTIVE;
// let view4 = new ViewController(Page4);
// view4.state = STATE_TRANS_ENTER;
// let view5 = new ViewController(Page5);
// view5.state = STATE_INACTIVE;
// nav._views = [view1, view2, view3, view4, view5];
// nav._cleanup();
// expect(nav.length()).toBe(3);
// expect(nav.getByIndex(0).state).toBe(STATE_INACTIVE);
// expect(nav.getByIndex(0).component).toBe(Page1);
// expect(nav.getByIndex(1).state).toBe(STATE_ACTIVE);
// expect(nav.getByIndex(1).component).toBe(Page2);
// expect(nav.getByIndex(2).state).toBe(STATE_TRANS_ENTER);
// expect(nav.getByIndex(2).component).toBe(Page4);
// });
// it('should not destroy any views since the last is active', () => {
// let view1 = new ViewController(Page1);
// view1.state = STATE_INACTIVE;
// let view2 = new ViewController(Page2);
// view2.state = STATE_ACTIVE;
// nav._views = [view1, view2];
// nav._cleanup();
// expect(nav.length()).toBe(2);
// });
// it('should call destroy for each view to be destroyed', () => {
// let view1 = new ViewController(Page1);
// view1.state = STATE_ACTIVE;
// let view2 = new ViewController(Page2);
// view2.state = STATE_INACTIVE;
// let view3 = new ViewController(Page3);
// view3.state = STATE_INACTIVE;
// nav._views = [view1, view2, view3];
// spyOn(view1, 'destroy');
// spyOn(view2, 'destroy');
// spyOn(view3, 'destroy');
// nav._cleanup();
// expect(nav.length()).toBe(1);
// expect(view1._willUnload).not.toHaveBeenCalled();
// expect(view2._willUnload).toHaveBeenCalled();
// expect(view3._willUnload).toHaveBeenCalled();
// });
// it('should reset zIndexes if their is a negative zindex', () => {
// let view1 = new ViewController(Page1);
// view1._setPageElementRef( mockElementRef() );
// view1.state = STATE_INACTIVE;
// view1._zIndex = -1;
// let view2 = new ViewController(Page2);
// view2._setPageElementRef( mockElementRef() );
// view2.state = STATE_INACTIVE;
// view2._zIndex = 0;
// let view3 = new ViewController(Page3);
// view3._setPageElementRef( mockElementRef() );
// view3.state = STATE_ACTIVE;
// view3._zIndex = 1;
// nav._views = [view1, view2, view3];
// nav._cleanup();
// expect(view1._zIndex).toEqual(100);
// expect(view2._zIndex).toEqual(101);
// expect(view3._zIndex).toEqual(102);
// });
// });
let nav: NavControllerBase;
let trnsDone: jasmine.Spy;

View File

@ -1,7 +1,7 @@
import { ComponentRef, ElementRef, EventEmitter, Output, Renderer } from '@angular/core';
import { Footer, Header } from '../components/toolbar/toolbar';
import { isPresent, assign } from '../util/util';
import { isPresent } from '../util/util';
import { Navbar } from '../components/navbar/navbar';
import { NavController } from './nav-controller';
import { NavOptions, ViewState } from './nav-util';
@ -79,6 +79,16 @@ export class ViewController {
*/
willUnload: EventEmitter<any> = new EventEmitter();
/**
* @private
*/
readReady: EventEmitter<any> = new EventEmitter<any>();
/**
* @private
*/
writeReady: EventEmitter<any> = new EventEmitter<any>();
/** @private */
data: any;
@ -160,7 +170,7 @@ export class ViewController {
this._dismissData = data;
this._dismissRole = role;
const options = assign({}, this._leavingOpts, navOptions);
const options = Object.assign({}, this._leavingOpts, navOptions);
return this._nav.removeView(this, options).then(() => data);
}