diff --git a/src/animations/animation.ts b/src/animations/animation.ts
index 0ab680a6f3..03f59df759 100644
--- a/src/animations/animation.ts
+++ b/src/animations/animation.ts
@@ -4,25 +4,37 @@ import {assign, isDefined} from '../util/util';
/**
* @private
- **/
+ *
+ * - play
+ * - Add before classes - DOM WRITE
+ * - Remove before classes - DOM WRITE
+ * - Add before inline styles - DOM WRITE
+ * - set inline FROM styles - DOM WRITE
+ * - RAF
+ * - run before functions that have dom reads - DOM READ
+ * - run before functions that have dom writes - DOM WRITE
+ * - set css transition duration/easing - DOM WRITE
+ * - RAF
+ * - set inline TO styles - DOM WRITE
+ */
export class Animation {
private _parent: Animation;
- private _c: Animation[];
- private _el: HTMLElement[];
+ private _c: Animation[] = [];
+ private _el: HTMLElement[] = [];
private _opts: AnimationOptions;
- private _fx: {[key: string]: EffectProperty};
+ private _fx: {[key: string]: EffectProperty} = {};
private _dur: number;
private _easing: string;
- private _bfSty: { [property: string]: any; };
- private _bfAdd: string[];
- private _bfRmv: string[];
- private _afSty: { [property: string]: any; };
- private _afAdd: string[];
- private _afRmv: string[];
- private _pFns: Function[];
- private _fFns: Function[];
- private _fOnceFns: Function[];
- private _wChg: boolean = false;
+ private _bfSty: { [property: string]: any; } = {};
+ private _bfAdd: string[] = [];
+ private _bfRmv: string[] = [];
+ private _afSty: { [property: string]: any; } = {};
+ private _afAdd: string[] = [];
+ private _afRmv: string[] = [];
+ private _bfReadFns: Function[] = [];
+ private _bfWriteFns: Function[] = [];
+ private _fFns: Function[] = [];
+ private _fOnceFns: Function[] = [];
private _rv: boolean = false;
private _unregTrans: Function;
private _tmr: number;
@@ -33,7 +45,6 @@ export class Animation {
public hasCompleted: boolean = false;
constructor(ele?: any, opts: AnimationOptions = {}) {
- this._reset();
this.element(ele);
this._opts = assign({
@@ -41,22 +52,15 @@ export class Animation {
}, opts);
}
+ /**
+ * NO DOM
+ */
_reset() {
- this._el = [];
- this._c = [];
this._fx = {};
-
this._bfSty = {};
- this._bfAdd = [];
- this._bfRmv = [];
this._afSty = {};
- this._afAdd = [];
- this._afRmv = [];
-
- this._pFns = [];
- this._fFns = [];
- this._fOnceFns = [];
+ this._el.length = this._c.length = this._bfAdd.length = this._bfRmv.length = this._afAdd.length = this._afRmv.length = this._fFns.length = this._bfReadFns.length = this._bfWriteFns.length = this._fOnceFns.length = 0;
this._easing = this._dur = null;
}
@@ -83,6 +87,9 @@ export class Animation {
return this;
}
+ /**
+ * NO DOM
+ */
private _addEle(ele: any) {
if (ele.nativeElement) {
ele = ele.nativeElement;
@@ -90,46 +97,67 @@ export class Animation {
if (ele.nodeType === 1) {
this._el.push(ele);
-
- // does this element suport will-change property?
- this._wChg = (typeof ele.style.willChange !== 'undefined');
}
}
+ /**
+ * NO DOM
+ */
parent(parentAnimation: Animation): Animation {
this._parent = parentAnimation;
return this;
}
+ /**
+ * NO DOM
+ */
add(childAnimation: Animation): Animation {
childAnimation.parent(this);
this._c.push(childAnimation);
return this;
}
+ /**
+ * NO DOM
+ */
getDuration(): number {
return this._dur !== null ? this._dur : (this._parent && this._parent.getDuration()) || 0;
}
+ /**
+ * NO DOM
+ */
duration(milliseconds: number): Animation {
this._dur = milliseconds;
return this;
}
+ /**
+ * NO DOM
+ */
getEasing(): string {
return this._easing !== null ? this._easing : (this._parent && this._parent.getEasing()) || null;
}
+ /**
+ * NO DOM
+ */
easing(name: string): Animation {
this._easing = name;
return this;
}
+ /**
+ * NO DOM
+ */
from(prop: string, val: any): Animation {
this._addProp('from', prop, val);
return this;
}
+ /**
+ * NO DOM
+ */
to(prop: string, val: any, clearProperyAfterTransition?: boolean): Animation {
var fx: EffectProperty = this._addProp('to', prop, val);
@@ -142,10 +170,16 @@ export class Animation {
return this;
}
+ /**
+ * NO DOM
+ */
fromTo(prop: string, fromVal: any, toVal: any, clearProperyAfterTransition?: boolean): Animation {
return this.from(prop, fromVal).to(prop, toVal, clearProperyAfterTransition);
}
+ /**
+ * NO DOM
+ */
private _addProp(state: string, prop: string, val: any): EffectProperty {
var fxProp: EffectProperty = this._fx[prop];
@@ -166,7 +200,7 @@ export class Animation {
}
// add from/to EffectState to the EffectProperty
- var fxState = fxProp[state] = {
+ var fxState: EffectState = fxProp[state] = {
val: val,
num: null,
unit: '',
@@ -188,14 +222,9 @@ export class Animation {
return fxProp;
}
- fadeIn(): Animation {
- return this.fromTo('opacity', 0.001, 1, true);
- }
-
- fadeOut(): Animation {
- return this.fromTo('opacity', 0.999, 0);
- }
-
+ /**
+ * NO DOM
+ */
get before() {
return {
addClass: (className: string): Animation => {
@@ -215,10 +244,21 @@ export class Animation {
this._bfSty[propertyNames[i]] = '';
}
return this;
+ },
+ addDomReadFn: (domReadFn: Function): Animation => {
+ this._bfReadFns.push(domReadFn);
+ return this;
+ },
+ addDomWriteFn: (domWriteFn: Function): Animation => {
+ this._bfWriteFns.push(domWriteFn);
+ return this;
}
};
}
+ /**
+ * NO DOM
+ */
get after() {
return {
addClass: (className: string): Animation => {
@@ -242,12 +282,18 @@ export class Animation {
};
}
+ /**
+ * DOM WRITE
+ */
play(opts: PlayOptions = {}) {
var self = this;
var i: number;
- var duration: number = isDefined(opts.duration) ? opts.duration : self._dur;
- console.debug('Animation, play, duration', duration, 'easing', self._easing);
+ if (isDefined(opts.duration)) {
+ self._dur = opts.duration;
+ }
+
+ console.debug('Animation, play, duration', self._dur, 'easing', self._easing);
// always default that an animation does not tween
// a tween requires that an Animation class has an element
@@ -255,11 +301,6 @@ export class Animation {
// and that the FROM/TO effect can tween numeric values
self.hasTween = false;
self.hasCompleted = false;
-
- // fire off all the onPlays
- for (i = 0; i < self._pFns.length; i++) {
- self._pFns[i]();
- }
self.isPlaying = true;
// this is the top level animation and is in full control
@@ -269,34 +310,51 @@ export class Animation {
// FROM property and transition duration, wait a few frames, then
// kick off the animation by setting the TO property for each animation
- // stage all of the before css classes and inline styles
- // will recursively stage all child elements
- self._before();
-
// ensure all past transition end events have been cleared
self._clearAsync();
- if (duration > 30) {
+ if (self._dur > 30) {
// this animation has a duration, so it should animate
// place all the elements with their FROM properties
// set the FROM properties
+ // ******** DOM WRITE ****************
self._progress(0);
// add the will-change or translateZ properties when applicable
+ // ******** DOM WRITE ****************
self._willChg(true);
// set the async TRANSITION END event
// and run onFinishes when the transition ends
- self._asyncEnd(duration, true);
+ // ******** DOM WRITE ****************
+ self._asyncEnd(self._dur, true);
// begin each animation when everything is rendered in their place
// and the transition duration/easing is ready to go
rafFrames(self._opts.renderDelay / 16, function() {
// there's been a moment and the elements are in place
+ // fire off all the "before" function that have DOM READS in them
+ // elements will be in the DOM, however visibily hidden
+ // so we can read their dimensions if need be
+ // ******** DOM READ ****************
+ self._beforeReadFn();
+
+ // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
+
+ // fire off all the "before" function that have DOM WRITES in them
+ // ******** DOM WRITE ****************
+ self._beforeWriteFn();
+
+ // stage all of the before css classes and inline styles
+ // will recursively stage all child elements
+ // ******** DOM WRITE ****************
+ self._before();
+
// now set the TRANSITION duration/easing
- self._setTrans(duration, false);
+ // ******** DOM WRITE ****************
+ self._setTrans(self._dur, false);
// wait a few moments again to wait for the transition
// info to take hold in the DOM
@@ -305,25 +363,55 @@ export class Animation {
// and the transition duration/easing is set
// now set the TO properties
// which will trigger the transition to begin
+ // ******** DOM WRITE ****************
self._progress(1);
});
});
} else {
- // this animation does not have a duration, so it should not animate
- // just go straight to the TO properties and call it done
- self._progress(1);
+ // this animation does not have a duration
+ // but we still need to apply the styles and wait
+ // a frame so we can accurately read the dimensions
+ rafFrames(self._opts.renderDelay / 16, function() {
- // since there was no animation, immediately run the after
- self._after();
+ // fire off all the "before" function that have DOM READS in them
+ // elements will be in the DOM, however visibily hidden
+ // so we can read their dimensions if need be
+ // ******** DOM READ ****************
+ self._beforeReadFn();
- // since there was no animation, it's done
- // fire off all the onFinishes
- self._didFinish(true);
+ // ******** DOM READS ABOVE / DOM WRITES BELOW ****************
+
+ // fire off all the "before" function that have DOM WRITES in them
+ // ******** DOM WRITE ****************
+ self._beforeWriteFn();
+
+ // ensure before css has ran
+ // ******** DOM WRITE ****************
+ self._before();
+
+ // this animation does not have a duration, so it should not animate
+ // just go straight to the TO properties and call it done
+ // ******** DOM WRITE ****************
+ self._progress(1);
+
+ // since there was no animation, immediately run the after
+ // ******** DOM WRITE ****************
+ self._after();
+
+ // since there was no animation, it's done
+ // fire off all the onFinishes
+ // and now you know
+ self._didFinish(true);
+
+ });
}
}
+ /**
+ * DOM WRITE
+ */
stop(opts: PlayOptions = {}) {
var self = this;
var duration = isDefined(opts.duration) ? opts.duration : 0;
@@ -333,6 +421,7 @@ export class Animation {
this._clearAsync();
// set the TO properties
+ // ******** DOM WRITE ****************
self._progress(stepValue);
if (duration > 30) {
@@ -340,15 +429,18 @@ export class Animation {
// place all the elements with their TO properties
// now set the TRANSITION duration
+ // ******** DOM WRITE ****************
self._setTrans(duration, true);
// set the async TRANSITION END event
// and run onFinishes when the transition ends
+ // ******** DOM WRITE ****************
self._asyncEnd(duration, false);
} else {
// this animation does not have a duration, so it should not animate
// just go straight to the TO properties and call it done
+ // ******** DOM WRITE ****************
self._after();
// since there was no animation, it's done
@@ -357,6 +449,9 @@ export class Animation {
}
}
+ /**
+ * DOM WRITE
+ */
_asyncEnd(duration: number, shouldComplete: boolean) {
var self = this;
@@ -367,9 +462,11 @@ export class Animation {
self._clearAsync();
// set the after styles
+ // ******** DOM WRITE ****************
self._after();
// remove will change properties
+ // ******** DOM WRITE ****************
self._willChg(false);
// transition finished
@@ -386,15 +483,19 @@ export class Animation {
self._clearAsync();
// too late to have a smooth animation, just finish it
+ // ******** DOM WRITE ****************
self._setTrans(0, true);
// ensure the ending progress step gets rendered
+ // ******** DOM WRITE ****************
self._progress(1);
// set the after styles
+ // ******** DOM WRITE ****************
self._after();
// remove will change properties
+ // ******** DOM WRITE ****************
self._willChg(false);
// transition finished
@@ -409,6 +510,9 @@ export class Animation {
self._tmr = nativeTimeout(onTransitionFallback, duration + 400);
}
+ /**
+ * NO DOM
+ */
_clearAsync() {
this._unregTrans && this._unregTrans();
if (this._tmr) {
@@ -417,6 +521,9 @@ export class Animation {
}
}
+ /**
+ * DOM WRITE
+ */
_progress(stepValue: number) {
// bread 'n butter
var i: number;
@@ -427,6 +534,7 @@ export class Animation {
var tweenEffect: boolean;
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i]._progress(stepValue);
}
@@ -469,6 +577,7 @@ export class Animation {
} else {
for (i = 0; i < this._el.length; i++) {
+ // ******** DOM WRITE ****************
this._el[i].style[prop] = val;
}
}
@@ -479,13 +588,14 @@ export class Animation {
// place all transforms on the same property
if (transforms.length) {
- if (!this._wChg) {
+ if (!SUPPORTS_WILL_CHANGE) {
// if the element doesn't support will-change
// then auto add translateZ for transform properties
transforms.push('translateZ(0px)');
}
for (i = 0; i < this._el.length; i++) {
+ // ******** DOM WRITE ****************
this._el[i].style[CSS.transform] = transforms.join(' ');
}
}
@@ -494,39 +604,49 @@ export class Animation {
}
+ /**
+ * DOM WRITE
+ */
_setTrans(duration: number, forcedLinearEasing: boolean) {
var i: number;
var easing: string;
// set the TRANSITION properties inline on the element
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i]._setTrans(duration, forcedLinearEasing);
}
if (Object.keys(this._fx).length) {
for (i = 0; i < this._el.length; i++) {
// all parent/child animations should have the same duration
+ // ******** DOM WRITE ****************
this._el[i].style[CSS.transitionDuration] = duration + 'ms';
// each animation can have a different easing
easing = (forcedLinearEasing ? 'linear' : this.getEasing());
if (easing) {
+ // ******** DOM WRITE ****************
this._el[i].style[CSS.transitionTimingFn] = easing;
}
}
}
}
+ /**
+ * DOM WRITE
+ */
_willChg(addWillChange: boolean) {
var i: number;
var wc: string[];
var prop: string;
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i]._willChg(addWillChange);
}
- if (this._wChg) {
+ if (SUPPORTS_WILL_CHANGE) {
wc = [];
if (addWillChange) {
@@ -538,11 +658,15 @@ export class Animation {
}
for (i = 0; i < this._el.length; i++) {
+ // ******** DOM WRITE ****************
this._el[i].style['willChange'] = wc.join(',');
}
}
}
+ /**
+ * DOM WRITE
+ */
_before() {
// before the RENDER_DELAY
// before the animations have started
@@ -553,6 +677,7 @@ export class Animation {
// stage all of the child animations
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i]._before();
}
@@ -562,22 +687,62 @@ export class Animation {
// css classes to add before the animation
for (j = 0; j < this._bfAdd.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.add(this._bfAdd[j]);
}
// css classes to remove before the animation
for (j = 0; j < this._bfRmv.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.remove(this._bfRmv[j]);
}
// inline styles to add before the animation
for (prop in this._bfSty) {
+ // ******** DOM WRITE ****************
ele.style[prop] = this._bfSty[prop];
}
}
}
}
+ /**
+ * DOM READ
+ */
+ _beforeReadFn() {
+ var i: number;
+
+ for (i = 0; i < this._c.length; i++) {
+ // ******** DOM READ ****************
+ this._c[i]._beforeReadFn();
+ }
+
+ for (i = 0; i < this._bfReadFns.length; i++) {
+ // ******** DOM READ ****************
+ this._bfReadFns[i]();
+ }
+ }
+
+ /**
+ * DOM WRITE
+ */
+ _beforeWriteFn() {
+ var i: number;
+
+ for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
+ this._c[i]._beforeWriteFn();
+ }
+
+ for (i = 0; i < this._bfReadFns.length; i++) {
+ // ******** DOM WRITE ****************
+ this._bfWriteFns[i]();
+ }
+ }
+
+ /**
+ * DOM WRITE
+ */
_after() {
// after the animations have finished
var i: number;
@@ -586,6 +751,7 @@ export class Animation {
var ele: HTMLElement;
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i]._after();
}
@@ -593,7 +759,9 @@ export class Animation {
ele = this._el[i];
// remove the transition duration/easing
+ // ******** DOM WRITE ****************
ele.style[CSS.transitionDuration] = '';
+ // ******** DOM WRITE ****************
ele.style[CSS.transitionTimingFn] = '';
if (this._rv) {
@@ -601,16 +769,19 @@ export class Animation {
// css classes that were added before the animation should be removed
for (j = 0; j < this._bfAdd.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.remove(this._bfAdd[j]);
}
// css classes that were removed before the animation should be added
for (j = 0; j < this._bfRmv.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.add(this._bfRmv[j]);
}
// inline styles that were added before the animation should be removed
for (prop in this._bfSty) {
+ // ******** DOM WRITE ****************
ele.style[prop] = '';
}
@@ -619,16 +790,19 @@ export class Animation {
// css classes to add after the animation
for (j = 0; j < this._afAdd.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.add(this._afAdd[j]);
}
// css classes to remove after the animation
for (j = 0; j < this._afRmv.length; j++) {
+ // ******** DOM WRITE ****************
ele.classList.remove(this._afRmv[j]);
}
// inline styles to add after the animation
for (prop in this._afSty) {
+ // ******** DOM WRITE ****************
ele.style[prop] = this._afSty[prop];
}
}
@@ -636,17 +810,26 @@ export class Animation {
}
+ /**
+ * DOM WRITE
+ */
progressStart() {
for (var i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i].progressStart();
}
+ // ******** DOM WRITE ****************
this._before();
// force no duration, linear easing
+ // ******** DOM WRITE ****************
this._setTrans(0, true);
}
+ /**
+ * DOM WRITE
+ */
progressStep(stepValue: number) {
let now = Date.now();
@@ -657,6 +840,7 @@ export class Animation {
stepValue = Math.min(1, Math.max(0, stepValue));
for (var i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i].progressStep(stepValue);
}
@@ -666,18 +850,24 @@ export class Animation {
stepValue = ((stepValue * -1) + 1);
}
+ // ******** DOM WRITE ****************
this._progress(stepValue);
}
}
+ /**
+ * DOM WRITE
+ */
progressEnd(shouldComplete: boolean, currentStepValue: number) {
console.debug('Animation, progressEnd, shouldComplete', shouldComplete, 'currentStepValue', currentStepValue);
for (var i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i].progressEnd(shouldComplete, currentStepValue);
}
// set all the animations to their final position
+ // ******** DOM WRITE ****************
this._progress(shouldComplete ? 1 : 0);
// if it's already at the final position, or close, then it's done
@@ -685,25 +875,29 @@ export class Animation {
if (currentStepValue < 0.05 || currentStepValue > 0.95) {
// the progress was already left off at the point that is finished
// for example, the left menu was dragged all the way open already
+ // ******** DOM WRITE ****************
this._after();
+
+ // ******** DOM WRITE ****************
this._willChg(false);
+
this._didFinish(shouldComplete);
} else {
// the stepValue was left off at a point when it needs to finish transition still
// for example, the left menu was opened 75% and needs to finish opening
+ // ******** DOM WRITE ****************
this._asyncEnd(64, shouldComplete);
// force quick duration, linear easing
+ // ******** DOM WRITE ****************
this._setTrans(64, true);
}
}
- onPlay(callback: Function): Animation {
- this._pFns.push(callback);
- return this;
- }
-
+ /**
+ * POSSIBLE DOM READ/WRITE
+ */
onFinish(callback: Function, onceTimeCallback: boolean = false, clearOnFinishCallacks: boolean = false): Animation {
if (clearOnFinishCallacks) {
this._fFns = [];
@@ -718,6 +912,9 @@ export class Animation {
return this;
}
+ /**
+ * POSSIBLE DOM READ/WRITE
+ */
_didFinish(hasCompleted: boolean) {
this.isPlaying = false;
this.hasCompleted = hasCompleted;
@@ -732,6 +929,9 @@ export class Animation {
this._fOnceFns = [];
}
+ /**
+ * NO DOM
+ */
reverse(shouldReverse: boolean = true): Animation {
for (var i = 0; i < this._c.length; i++) {
this._c[i].reverse(shouldReverse);
@@ -740,17 +940,22 @@ export class Animation {
return this;
}
+ /**
+ * DOM WRITE
+ */
destroy(removeElement?: boolean) {
var i: number;
var ele: HTMLElement;
for (i = 0; i < this._c.length; i++) {
+ // ******** DOM WRITE ****************
this._c[i].destroy(removeElement);
}
if (removeElement) {
for (i = 0; i < this._el.length; i++) {
ele = this._el[i];
+ // ******** DOM WRITE ****************
ele.parentNode && ele.parentNode.removeChild(ele);
}
}
@@ -759,6 +964,9 @@ export class Animation {
this._reset();
}
+ /**
+ * NO DOM
+ */
_transEl(): HTMLElement {
// get the lowest level element that has an Animation
var i: number;
@@ -774,9 +982,9 @@ export class Animation {
return (this.hasTween && this._el.length ? this._el[0] : null);
}
- /*
- STATIC CLASSES
- */
+
+ // ***** STATIC CLASSES *********
+
static create(name: string, opts: AnimationOptions = {}): Animation {
let AnimationClass = AnimationRegistry[name];
@@ -825,5 +1033,6 @@ const TRANSFORMS: any = {
};
const CSS_VALUE_REGEX = /(^-?\d*\.?\d*)(.*)/;
+const SUPPORTS_WILL_CHANGE = (typeof document.documentElement.style['willChange'] !== 'undefined');
let AnimationRegistry: any = {};
diff --git a/src/animations/builtins.ts b/src/animations/builtins.ts
index 25200d7750..367c6cfc9f 100644
--- a/src/animations/builtins.ts
+++ b/src/animations/builtins.ts
@@ -32,7 +32,7 @@ class FadeIn extends Animation {
this
.easing('ease-in')
.duration(400)
- .fadeIn();
+ .fromTo('opacity', 0.001, 1, true);
}
}
Animation.register('fade-in', FadeIn);
@@ -44,7 +44,7 @@ class FadeOut extends Animation {
this
.easing('ease-out')
.duration(250)
- .fadeOut();
+ .fromTo('opacity', 0.999, 0);
}
}
Animation.register('fade-out', FadeOut);
diff --git a/src/components/action-sheet/action-sheet.ts b/src/components/action-sheet/action-sheet.ts
index aa6e5abe5f..ec52b560c0 100644
--- a/src/components/action-sheet/action-sheet.ts
+++ b/src/components/action-sheet/action-sheet.ts
@@ -377,7 +377,7 @@ export interface ActionSheetOptions {
class ActionSheetSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -394,7 +394,7 @@ Transition.register('action-sheet-slide-in', ActionSheetSlideIn);
class ActionSheetSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -411,7 +411,7 @@ Transition.register('action-sheet-slide-out', ActionSheetSlideOut);
class ActionSheetMdSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -428,7 +428,7 @@ Transition.register('action-sheet-md-slide-in', ActionSheetMdSlideIn);
class ActionSheetMdSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -444,7 +444,7 @@ Transition.register('action-sheet-md-slide-out', ActionSheetMdSlideOut);
class ActionSheetWpSlideIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -461,7 +461,7 @@ Transition.register('action-sheet-wp-slide-in', ActionSheetWpSlideIn);
class ActionSheetWpSlideOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
diff --git a/src/components/alert/alert.ts b/src/components/alert/alert.ts
index 49c0a500d3..0716e27805 100644
--- a/src/components/alert/alert.ts
+++ b/src/components/alert/alert.ts
@@ -571,7 +571,7 @@ class AlertCmp {
// this is an alert with text inputs
// return an object of all the values with the input name as the key
- let values = {};
+ let values: {[k: string]: string} = {};
this.d.inputs.forEach(i => {
values[i.name] = i.value;
});
@@ -605,14 +605,14 @@ export interface AlertInputOptions {
*/
class AlertPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
- backdrop.fromTo('opacity', '0.01', '0.3');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
+ backdrop.fromTo('opacity', 0.01, 0.3);
this
.easing('ease-in-out')
@@ -626,14 +626,14 @@ Transition.register('alert-pop-in', AlertPopIn);
class AlertPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
- backdrop.fromTo('opacity', '0.3', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
+ backdrop.fromTo('opacity', 0.3, 0);
this
.easing('ease-in-out')
@@ -647,14 +647,14 @@ Transition.register('alert-pop-out', AlertPopOut);
class AlertMdPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
- backdrop.fromTo('opacity', '0.01', '0.5');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
+ backdrop.fromTo('opacity', 0.01, 0.5);
this
.easing('ease-in-out')
@@ -668,14 +668,14 @@ Transition.register('alert-md-pop-in', AlertMdPopIn);
class AlertMdPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
- backdrop.fromTo('opacity', '0.5', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
+ backdrop.fromTo('opacity', 0.5, 0);
this
.easing('ease-in-out')
@@ -690,14 +690,14 @@ Transition.register('alert-md-pop-out', AlertMdPopOut);
class AlertWpPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.3', '1');
- backdrop.fromTo('opacity', '0.01', '0.5');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
+ backdrop.fromTo('opacity', 0.01, 0.5);
this
.easing('cubic-bezier(0,0 0.05,1)')
@@ -711,14 +711,14 @@ Transition.register('alert-wp-pop-in', AlertWpPopIn);
class AlertWpPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.alert-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '1.3');
- backdrop.fromTo('opacity', '0.5', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
+ backdrop.fromTo('opacity', 0.5, 0);
this
.easing('ease-out')
diff --git a/src/components/app/structure.scss b/src/components/app/structure.scss
index 3b7a50600e..3805777523 100644
--- a/src/components/app/structure.scss
+++ b/src/components/app/structure.scss
@@ -15,6 +15,8 @@ $z-index-refresher: 0;
$z-index-navbar-section: 10;
+$z-index-page-container: 0;
+$z-index-selected-tab: 1;
$z-index-toolbar: 10;
$z-index-toolbar-background: -1;
@@ -85,64 +87,138 @@ body {
text-size-adjust: none;
}
-ion-app.app-init,
+
+// Nav Container Structure
+// --------------------------------------------------
+
+ion-app,
ion-nav,
+ion-tab,
ion-tabs {
position: absolute;
top: 0;
left: 0;
- display: flex;
+ z-index: $z-index-page-container;
+ display: block;
overflow: hidden;
- flex-direction: column;
-
width: 100%;
height: 100%;
}
-ion-navbar-section {
- display: block;
-
- width: 100%;
- min-height: 50px;
+ion-tab scroll-cotent {
+ display: none;
}
-ion-content-section {
- position: relative;
- display: block;
-
- flex: 1;
-
- width: 100%;
- height: 100%;
+ion-tab.show-tab {
+ z-index: $z-index-selected-tab;
}
+ion-tab.show-tab scroll-cotent {
+ display: block;
+}
+
+
+// Page Container Structure
+// --------------------------------------------------
+
ion-page {
position: absolute;
top: 0;
left: 0;
- display: none;
-
- flex-direction: column;
+ display: block;
width: 100%;
height: 100%;
- &.show-page {
- display: flex;
- }
+ // do not show, but still render so we can get dimensions
+ visibility: hidden;
}
ion-content {
position: relative;
+ top: 0;
+ left: 0;
display: block;
- flex: 1;
-
width: 100%;
height: 100%;
}
+ion-page > ion-content {
+ position: absolute;
+}
+
+ion-page scroll-content {
+ // do not render the scroll-content at all until ready
+ display: none;
+}
+
+ion-page.show-page {
+ // show the page now that it's ready
+ visibility: visible;
+}
+
+ion-page.show-page scroll-content {
+ // render the content when ready
+ display: block;
+}
+
+ion-page.tab-subpage {
+ position: fixed;
+ z-index: 10;
+}
+
+
+// Toolbar Container Structure
+// --------------------------------------------------
+
+ion-header {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: $z-index-toolbar;
+ display: block;
+
+ width: 100%;
+}
+
+ion-footer {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ z-index: $z-index-toolbar;
+ display: block;
+
+ width: 100%;
+}
+
+ion-tabbar {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ z-index: $z-index-toolbar;
+ display: flex;
+
+ width: 100%;
+
+ // default to hidden until ready
+ visibility: hidden;
+}
+
+ion-tabbar.show-tabbar {
+ visibility: visible;
+}
+
+[tabbarPlacement=top] > ion-tabbar {
+ top: 0;
+ bottom: auto;
+}
+
+
+// Scrollable Content
+// --------------------------------------------------
+
scroll-content {
position: absolute;
top: 0;
@@ -169,59 +245,9 @@ ion-content.js-scroll > scroll-content {
will-change: initial;
}
-ion-tabbar {
- position: absolute;
- top: 0;
- left: 0;
- display: block;
- width: 100%;
- min-height: 50px;
-}
-
-ion-tab-section {
- position: relative;
- top: 0;
- left: 0;
- display: block;
- overflow: hidden;
-
- width: 100%;
- height: 100%;
-}
-
-ion-page.tab-subpage {
- position: fixed;
- z-index: 10;
-}
-
-ion-navbar {
- position: absolute;
- top: 0;
- left: 0;
- z-index: $z-index-navbar-section;
- display: block;
-
- width: 100%;
- min-height: 50px;
-}
-
-ion-navbar-section ion-navbar.toolbar {
- position: absolute;
-}
-
-ion-toolbar {
- display: block;
-
- width: 100%;
-}
-
-ion-toolbar[position=bottom] {
- bottom: 0;
- z-index: $z-index-toolbar;
-}
-
-.sticky {
- position: sticky;
- top: 0;
-}
+[nav-viewport],
+[nav-portal],
+[tab-portal] {
+ display: none;
+}
\ No newline at end of file
diff --git a/src/components/content/content.ts b/src/components/content/content.ts
index 0ab440e4c9..9057578e9a 100644
--- a/src/components/content/content.ts
+++ b/src/components/content/content.ts
@@ -57,7 +57,9 @@ import {ScrollView} from '../../util/scroll-view';
}
})
export class Content extends Ion {
- private _padding: number = 0;
+ private _paddingTop: number = 0;
+ private _paddingBottom: number = 0;
+ private _scrollPadding: number = 0;
private _inputPolling: boolean = false;
private _scroll: ScrollView;
private _scLsn: Function;
@@ -370,14 +372,24 @@ export class Content extends Ion {
* so content below the keyboard can be scrolled into view.
*/
addScrollPadding(newPadding: number) {
- if (newPadding > this._padding) {
+ if (newPadding > this._scrollPadding) {
console.debug('content addScrollPadding', newPadding);
- this._padding = newPadding;
+ this._scrollPadding = newPadding;
this._scrollEle.style.paddingBottom = newPadding + 'px';
}
}
+ /**
+ * @private
+ */
+ setContentPadding(paddingTop: number, paddingBottom: number) {
+ this._paddingTop = paddingTop;
+ this._paddingBottom = paddingBottom;
+ this._scrollEle.style.paddingTop = (paddingTop > 0 ? paddingTop + 'px' : '');
+ this._scrollEle.style.paddingBottom = (paddingBottom > 0 ? paddingBottom + 'px' : '');
+ }
+
/**
* @private
*/
@@ -386,8 +398,8 @@ export class Content extends Ion {
this._inputPolling = true;
this._keyboard.onClose(() => {
- this._padding = 0;
- this._scrollEle.style.paddingBottom = '';
+ this._scrollPadding = 0;
+ this._scrollEle.style.paddingBottom = (this._paddingBottom > 0 ? this._paddingBottom + 'px' : '');
this._inputPolling = false;
this.addScrollPadding(0);
}, 200, Infinity);
diff --git a/src/components/loading/loading.ts b/src/components/loading/loading.ts
index 1275d27678..17fd6f98c3 100644
--- a/src/components/loading/loading.ts
+++ b/src/components/loading/loading.ts
@@ -230,14 +230,14 @@ export interface LoadingOptions {
*/
class LoadingPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
- backdrop.fromTo('opacity', '0.01', '0.3');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
+ backdrop.fromTo('opacity', 0.01, 0.3);
this
.easing('ease-in-out')
@@ -251,14 +251,14 @@ export interface LoadingOptions {
class LoadingPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
- backdrop.fromTo('opacity', '0.3', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
+ backdrop.fromTo('opacity', 0.3, 0);
this
.easing('ease-in-out')
@@ -272,14 +272,14 @@ export interface LoadingOptions {
class LoadingMdPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
- backdrop.fromTo('opacity', '0.01', '0.50');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.1, 1);
+ backdrop.fromTo('opacity', 0.01, 0.5);
this
.easing('ease-in-out')
@@ -293,14 +293,14 @@ export interface LoadingOptions {
class LoadingMdPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
- backdrop.fromTo('opacity', '0.50', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 0.9);
+ backdrop.fromTo('opacity', 0.5, 0);
this
.easing('ease-in-out')
@@ -314,14 +314,14 @@ export interface LoadingOptions {
class LoadingWpPopIn extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.3', '1');
- backdrop.fromTo('opacity', '0.01', '0.16');
+ wrapper.fromTo('opacity', 0.01, 1).fromTo('scale', 1.3, 1);
+ backdrop.fromTo('opacity', 0.01, 0.16);
this
.easing('cubic-bezier(0,0 0.05,1)')
@@ -335,14 +335,14 @@ export interface LoadingOptions {
class LoadingWpPopOut extends Transition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
let wrapper = new Animation(ele.querySelector('.loading-wrapper'));
- wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '1.3');
- backdrop.fromTo('opacity', '0.16', '0');
+ wrapper.fromTo('opacity', 0.99, 0).fromTo('scale', 1, 1.3);
+ backdrop.fromTo('opacity', 0.16, 0);
this
.easing('ease-out')
diff --git a/src/components/modal/modal.ts b/src/components/modal/modal.ts
index fb8d913098..15fc460f4a 100644
--- a/src/components/modal/modal.ts
+++ b/src/components/modal/modal.ts
@@ -1,15 +1,15 @@
-import {Component, ComponentRef, ComponentResolver, ElementRef, HostListener, ViewChild, ViewContainerRef} from '@angular/core';
+import {Component, ComponentResolver, HostListener, ViewChild, ViewContainerRef} from '@angular/core';
import {addSelector} from '../../config/bootstrap';
import {Animation} from '../../animations/animation';
import {NavParams} from '../nav/nav-params';
import {isPresent, pascalCaseToDashCase} from '../../util/util';
import {Key} from '../../util/key';
-import {Transition, TransitionOptions} from '../../transitions/transition';
+import {PageTransition} from '../../transitions/page-transition';
+import {TransitionOptions} from '../../transitions/transition';
import {ViewController} from '../nav/view-controller';
import {windowDimensions} from '../../util/dom';
-import {nativeRaf, CSS} from '../../util/dom';
/**
* @name Modal
@@ -191,7 +191,7 @@ export class ModalCmp {
}
loadComponent(done: Function) {
- addSelector(this._navParams.data.componentType, 'ion-modal-inner');
+ addSelector(this._navParams.data.componentType, 'ion-page');
this._compiler.resolveComponent(this._navParams.data.componentType).then((componentFactory) => {
let componentRef = this.viewport.createComponent(componentFactory, this.viewport.length, this.viewport.parentInjector);
@@ -227,9 +227,9 @@ export class ModalCmp {
/**
* Animations for modals
*/
- class ModalSlideIn extends Transition {
+ class ModalSlideIn extends PageTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdropEle = ele.querySelector('ion-backdrop');
@@ -263,12 +263,12 @@ export class ModalCmp {
}
}
}
- Transition.register('modal-slide-in', ModalSlideIn);
+ PageTransition.register('modal-slide-in', ModalSlideIn);
-class ModalSlideOut extends Transition {
+class ModalSlideOut extends PageTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -290,12 +290,12 @@ class ModalSlideOut extends Transition {
.add(wrapper);
}
}
-Transition.register('modal-slide-out', ModalSlideOut);
+PageTransition.register('modal-slide-out', ModalSlideOut);
-class ModalMDSlideIn extends Transition {
+class ModalMDSlideIn extends PageTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = enteringView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -311,7 +311,7 @@ class ModalMDSlideIn extends Transition {
backdrop.fromTo('opacity', 0.01, 0.4);
wrapper.fromTo('translateY', '40px', '0px');
- wrapper.fromTo('opacity', '0.01', '1.0');
+ wrapper.fromTo('opacity', 0.01, 1);
const DURATION = 280;
const EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
@@ -328,12 +328,12 @@ class ModalMDSlideIn extends Transition {
}
}
}
-Transition.register('modal-md-slide-in', ModalMDSlideIn);
+PageTransition.register('modal-md-slide-in', ModalMDSlideIn);
-class ModalMDSlideOut extends Transition {
+class ModalMDSlideOut extends PageTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
- super(opts);
+ super(enteringView, leavingView, opts);
let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('ion-backdrop'));
@@ -341,7 +341,7 @@ class ModalMDSlideOut extends Transition {
backdrop.fromTo('opacity', 0.4, 0.0);
wrapper.fromTo('translateY', '0px', '40px');
- wrapper.fromTo('opacity', '1.0', '0.00');
+ wrapper.fromTo('opacity', 0.99, 0);
this
.element(leavingView.pageRef())
@@ -351,4 +351,4 @@ class ModalMDSlideOut extends Transition {
.add(backdrop);
}
}
-Transition.register('modal-md-slide-out', ModalMDSlideOut);
+PageTransition.register('modal-md-slide-out', ModalMDSlideOut);
diff --git a/src/components/nav/nav-controller.ts b/src/components/nav/nav-controller.ts
index 519bfd5d13..5c352eb155 100644
--- a/src/components/nav/nav-controller.ts
+++ b/src/components/nav/nav-controller.ts
@@ -1,4 +1,4 @@
-import {ViewContainerRef, ComponentResolver, ComponentRef, provide, ReflectiveInjector, ResolvedReflectiveProvider, ElementRef, NgZone, Renderer, EventEmitter} from '@angular/core';
+import {ViewContainerRef, ComponentResolver, ComponentFactory, ComponentRef, provide, ReflectiveInjector, ResolvedReflectiveProvider, ElementRef, NgZone, Renderer, EventEmitter} from '@angular/core';
import {addSelector} from '../../config/bootstrap';
import {App} from '../app/app';
@@ -1059,7 +1059,7 @@ export class NavController extends Ion {
// DOM WRITE
this.setTransitioning(true, 500);
- this.loadPage(enteringView, null, opts, () => {
+ this.loadPage(enteringView, this._viewport, opts, () => {
enteringView.fireLoaded();
this.viewDidLoad.emit(enteringView);
this._postRender(transId, enteringView, leavingView, isAlreadyTransitioning, opts, done);
@@ -1467,8 +1467,8 @@ export class NavController extends Ion {
/**
* @private
*/
- loadPage(view: ViewController, navbarContainerRef: ViewContainerRef, opts: NavOptions, done: Function) {
- if (!this._viewport || !view.componentType) {
+ loadPage(view: ViewController, viewport: ViewContainerRef, opts: NavOptions, done: Function) {
+ if (!viewport || !view.componentType) {
return;
}
@@ -1489,7 +1489,7 @@ export class NavController extends Ion {
let componentRef = componentFactory.create(childInjector, null, null);
- this._viewport.insert(componentRef.hostView, this._viewport.length);
+ viewport.insert(componentRef.hostView, viewport.length);
// a new ComponentRef has been created
// set the ComponentRef's instance to its ViewController
@@ -1518,30 +1518,6 @@ export class NavController extends Ion {
componentRef.destroy();
});
- if (!navbarContainerRef) {
- // there was not a navbar container ref already provided
- // so use the location of the actual navbar template
- navbarContainerRef = view.getNavbarViewRef();
- }
-
- // find a navbar template if one is in the page
- let navbarTemplateRef = view.getNavbarTemplateRef();
-
- // check if we have both a navbar ViewContainerRef and a template
- if (navbarContainerRef && navbarTemplateRef) {
- // let's now create the navbar view
- let navbarViewRef = navbarContainerRef.createEmbeddedView(navbarTemplateRef);
-
- view.onDestroy(() => {
- // manually destroy the navbar when the page is destroyed
- navbarViewRef.destroy();
- });
- }
-
- // options may have had a postLoad method
- // used mainly by tabs
- opts.postLoad && opts.postLoad(view);
-
// our job is done here
done(view);
});
@@ -1852,7 +1828,6 @@ export interface NavOptions {
keyboardClose?: boolean;
preload?: boolean;
transitionDelay?: number;
- postLoad?: Function;
progressAnimation?: boolean;
climbNav?: boolean;
ev?: any;
diff --git a/src/components/nav/nav.ts b/src/components/nav/nav.ts
index 819c97eac5..54bc2a942c 100644
--- a/src/components/nav/nav.ts
+++ b/src/components/nav/nav.ts
@@ -109,7 +109,7 @@ import {ViewController} from './view-controller';
*/
@Component({
selector: 'ion-nav',
- template: '
',
+ template: '',
directives: [NavPortal],
encapsulation: ViewEncapsulation.None,
})
diff --git a/src/components/nav/test/basic/index.ts b/src/components/nav/test/basic/index.ts
index 2c1bf10783..e9fe791646 100644
--- a/src/components/nav/test/basic/index.ts
+++ b/src/components/nav/test/basic/index.ts
@@ -13,15 +13,18 @@ class MyCmpTest{}
@Component({
template: `
-
- {{title}}
-
-
-
-
-
-
-
+
+
+ {{title}}
+
+
+
+
+
+
+
+
+
@@ -57,7 +60,7 @@ class MyCmpTest{}
directives: [MyCmpTest]
})
class FirstPage {
- pushPage;
+ pushPage = FullPage;
title = 'First Page';
pages: Array = [];
@ViewChild(Content) content: Content;
@@ -66,8 +69,6 @@ class FirstPage {
private nav: NavController,
private view: ViewController
) {
- this.pushPage = FullPage;
-
for (var i = 1; i <= 50; i++) {
this.pages.push(i);
}
@@ -201,12 +202,15 @@ class FullPage {
@Component({
template: `
-
- Primary Color Page Header
-
-
-
-
+
+
+ Primary Color Page Header
+
+
+
+
+
+
@@ -221,9 +225,12 @@ class FullPage {
-
- Footer
-
+
+
+
+ Footer
+
+
`
})
class PrimaryHeaderPage {
@@ -267,9 +274,12 @@ class PrimaryHeaderPage {
@Component({
template: `
-
- Another Page Header
-
+
+
+ Another Page Header
+
+
+
@@ -289,9 +299,11 @@ class PrimaryHeaderPage {
-
- Another Page Footer
-
+
+
+ Another Page Footer
+
+
`
})
class AnotherPage {
diff --git a/src/components/nav/view-controller.ts b/src/components/nav/view-controller.ts
index d93697ea19..3ca658db92 100644
--- a/src/components/nav/view-controller.ts
+++ b/src/components/nav/view-controller.ts
@@ -1,9 +1,11 @@
import {Output, EventEmitter, Type, TemplateRef, ViewContainerRef, ElementRef, Renderer, ChangeDetectorRef} from '@angular/core';
+import {Header, Footer} from '../toolbar/toolbar';
+import {isPresent, merge} from '../../util/util';
import {Navbar} from '../navbar/navbar';
import {NavController, NavOptions} from './nav-controller';
import {NavParams} from './nav-params';
-import {isPresent, merge} from '../../util/util';
+import {Tabs} from '../tabs/tabs';
/**
@@ -27,13 +29,13 @@ export class ViewController {
private _cntDir: any;
private _cntRef: ElementRef;
private _tbRefs: ElementRef[] = [];
- private _destroys: Function[] = [];
+ private _hdrDir: Header;
+ private _ftrDir: Footer;
+ private _destroyFn: Function;
private _hdAttr: string = null;
private _leavingOpts: NavOptions = null;
private _loaded: boolean = false;
private _nbDir: Navbar;
- private _nbTmpRef: TemplateRef