diff --git a/ionic/animations/animation.ts b/ionic/animations/animation.ts
index 2894fadcba..f464cfabf3 100644
--- a/ionic/animations/animation.ts
+++ b/ionic/animations/animation.ts
@@ -251,7 +251,7 @@ export class Animation {
});
}
- if (self._duration > 64) {
+ if (self._duration > 32) {
// begin each animation when everything is rendered in their starting point
// give the browser some time to render everything in place before starting
setTimeout(kickoff, this._opts.renderDelay);
@@ -550,7 +550,7 @@ class Animate {
this.toEffect = parseEffect(toEffect);
- this.shouldAnimate = (duration > 64);
+ this.shouldAnimate = (duration > 32);
if (!this.shouldAnimate) {
return inlineStyle(ele, this.toEffect);
diff --git a/ionic/components/app/structure.scss b/ionic/components/app/structure.scss
index 8c06d7903f..34b505f933 100644
--- a/ionic/components/app/structure.scss
+++ b/ionic/components/app/structure.scss
@@ -82,79 +82,123 @@ body {
background-color: $background-color;
}
-ion-app {
+ion-app,
+ion-nav,
+ion-tabs {
display: flex;
flex-direction: column;
-
- overflow: hidden;
- height: 100%;
- max-width: 100%;
- max-height: 100%;
- margin: 0;
- padding: 0;
-
-}
-
-ion-nav {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
height: 100%;
}
-ion-pane,
-ion-view.pane-view {
+ion-navbar-section {
+ display: block;
+ width: 100%;
+ min-height: 50px;
+}
+
+ion-content-section {
+ display: block;
+ flex: 1;
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+ion-page {
+ display: flex;
+ flex-direction: column;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ transform: translateZ(0);
+}
+
+ion-content {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 100%;
+ flex: 1;
+ background-color: $background-color;
+}
+
+scroll-content {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
- width: 100%;
- height: 100%;
- overflow: hidden;
-
- display: flex;
- flex-direction: column;
+ display: block;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ -webkit-overflow-scrolling: touch;
+ will-change: scroll-position;
}
-ion-view.pane-view {
- background: transparent;
-}
-
-ion-view {
- display: none;
+ion-tab-bar {
+ display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
+ min-height: 50px;
+}
+
+ion-tab-section {
+ display: block;
+ position: relative;
+ top: 0;
+ left: 0;
+ width: 100%;
height: 100%;
- flex-direction: column;
-
- background-color: $background-color;
-
- transform: translateZ(0px);
-
- &.show-view {
- display: flex;
- }
+ overflow: hidden;
}
-[no-navbar] > ion-navbar-section {
- display: none;
+ion-page.tab-subpage {
+ position: fixed;
+ z-index: 10;
}
-ion-navbar-section {
- position: relative;
- min-height: 4.4rem;
- z-index: $z-index-navbar-section;
+ion-navbar {
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ min-height: 50px;
+ z-index: 10;
}
-ion-content-section {
- position: relative;
- z-index: $z-index-content-section;
- flex: 1;
- order: $flex-order-view-content;
+ion-navbar-section ion-navbar.toolbar {
+ position: absolute;
}
-[hidden],
-template,
-root-anchor {
- display: none !important;
+ion-toolbar {
+ display: block;
+ width: 100%;
+ height: 50px;
+}
+
+ion-toolbar[position=bottom] {
+ bottom: 0;
+ z-index: 10;
+}
+
+ion-scrollbar {
+ position: fixed;
+ top: 0;
+ right: 0;
+ z-index: 10;
+ width: 10px;
+}
+
+.hide-navtive-scrollbar ion-content {
+ padding-right: 20px;
+ width: calc(100% + 20px);
}
diff --git a/ionic/components/button/button.scss b/ionic/components/button/button.scss
index eeb28cb16d..487944937f 100644
--- a/ionic/components/button/button.scss
+++ b/ionic/components/button/button.scss
@@ -29,7 +29,6 @@ button,
align-items: center;
justify-content: center;
- will-change: background-color, opacity;
transition: background-color, opacity 100ms linear;
margin: $button-margin;
diff --git a/ionic/components/content/content.scss b/ionic/components/content/content.scss
deleted file mode 100644
index e6b71c8744..0000000000
--- a/ionic/components/content/content.scss
+++ /dev/null
@@ -1,65 +0,0 @@
-
-// Content
-// --------------------------------------------------
-
-$content-background-color: $background-color !default;
-
-
-ion-content {
- position: relative;
- display: block;
- flex: 1;
- background-color: $content-background-color;
-}
-
-scroll-content {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- display: block;
- overflow-y: scroll; // has to be scroll for momentum scrolling, not auto
- overflow-x: hidden;
- -webkit-overflow-scrolling: touch;
- will-change: scroll-position;
-}
-
-
-
-// Content Padding
-// --------------------------------------------------
-
-$content-padding: 16px !default;
-
-
-[padding],
-[padding] > scroll-content {
- padding: $content-padding;
-}
-
-[padding-top] {
- padding-top: $content-padding;
-}
-
-[padding-right] {
- padding-right: $content-padding;
-}
-
-[padding-bottom] {
- padding-bottom: $content-padding;
-}
-
-[padding-left] {
- padding-left: $content-padding;
-}
-
-[padding-vertical] {
- padding-top: $content-padding;
- padding-bottom: $content-padding;
-}
-
-[padding-horizontal] {
- padding-right: $content-padding;
- padding-left: $content-padding;
-}
diff --git a/ionic/components/content/content.ts b/ionic/components/content/content.ts
index 6f36aa234c..2fca0a00b5 100644
--- a/ionic/components/content/content.ts
+++ b/ionic/components/content/content.ts
@@ -42,6 +42,7 @@ export class Content extends Ion {
if (viewCtrl) {
viewCtrl.setContent(this);
+ viewCtrl.setContentRef(elementRef);
}
}
diff --git a/ionic/components/menu/menu.ts b/ionic/components/menu/menu.ts
index aac93507f4..7c59d37a8b 100644
--- a/ionic/components/menu/menu.ts
+++ b/ionic/components/menu/menu.ts
@@ -138,6 +138,11 @@ export class Menu extends Ion {
this._type = new menuTypeCls(this);
this.type = type;
+
+ if (this.config.get('animate') === false) {
+ this._type.open.duration(33);
+ this._type.close.duration(33);
+ }
}
/**
diff --git a/ionic/components/modal/modal.scss b/ionic/components/modal/modal.scss
index 1c2881e1c1..63d2528bf3 100644
--- a/ionic/components/modal/modal.scss
+++ b/ionic/components/modal/modal.scss
@@ -10,22 +10,3 @@ $modal-inset-mode-right: 20% !default;
$modal-inset-mode-bottom: 20% !default;
$modal-inset-mode-left: 20% !default;
$modal-inset-mode-min-height: 240px !default;
-
-
-ion-modal {
- position: absolute;
- top: 0;
- z-index: $z-index-overlay;
- overflow: hidden;
- min-height: 100%;
- width: 100%;
- background-color: $modal-background-color;
-
- display: flex;
- flex-direction: column;
-
- transform: translate3d(0px, 100%, 0px);
- &.show-overlay {
- transform: translate3d(0px, 0px, 0px);
- }
-}
diff --git a/ionic/components/modal/modal.ts b/ionic/components/modal/modal.ts
index 2fdb6f4dfd..05fd95b13f 100644
--- a/ionic/components/modal/modal.ts
+++ b/ionic/components/modal/modal.ts
@@ -3,7 +3,6 @@ import {Injectable} from 'angular2/angular2';
import {OverlayController} from '../overlay/overlay-controller';
import {Config} from '../../config/config';
import {Animation} from '../../animations/animation';
-import {makeComponent} from '../../config/decorators';
import * as util from 'ionic/util';
/**
@@ -46,11 +45,7 @@ export class Modal {
* @returns {TODO} TODO
*/
open(componentType: Type, opts={}) {
- let modalComponent = makeComponent(componentType, {
- selector: 'ion-modal'
- });
-
- return this.ctrl.open(OVERLAY_TYPE, modalComponent, util.extend(this._defaults, opts));
+ return this.ctrl.open(OVERLAY_TYPE, componentType, util.extend(this._defaults, opts));
}
/**
diff --git a/ionic/components/nav-bar/modes/ios.scss b/ionic/components/nav-bar/modes/ios.scss
index d0d91f654b..1ccea60915 100644
--- a/ionic/components/nav-bar/modes/ios.scss
+++ b/ionic/components/nav-bar/modes/ios.scss
@@ -8,3 +8,7 @@ $navbar-ios-height: 4.4rem !default;
ion-navbar-section {
min-height: $navbar-ios-height;
}
+
+.back-button {
+ transform: translateZ(0px);
+}
diff --git a/ionic/components/nav-bar/nav-bar.scss b/ionic/components/nav-bar/nav-bar.scss
index 413cfbdfbd..e7b31f10f5 100644
--- a/ionic/components/nav-bar/nav-bar.scss
+++ b/ionic/components/nav-bar/nav-bar.scss
@@ -4,17 +4,11 @@
ion-navbar.toolbar {
- position: absolute;
- display: none;
-
- &.show-navbar {
- display: flex;
- }
+ display: flex;
}
.back-button {
- order: map-get($toolbar-order, backButton);
- transform: translateZ(0px);
+ order: map-get($toolbar-order, backButton);
display: none;
&.show-back-button {
diff --git a/ionic/components/nav-bar/nav-bar.ts b/ionic/components/nav-bar/nav-bar.ts
index 89c4869a58..533bfabc9c 100644
--- a/ionic/components/nav-bar/nav-bar.ts
+++ b/ionic/components/nav-bar/nav-bar.ts
@@ -1,4 +1,4 @@
-import {Component, Directive, Optional, ElementRef, Renderer, TemplateRef, forwardRef, Inject} from 'angular2/angular2';
+import {Component, Directive, Optional, ElementRef, Renderer, TemplateRef, forwardRef, Inject, ViewContainerRef} from 'angular2/angular2';
import {Ion} from '../ion';
import {Icon} from '../icon/icon';
@@ -65,6 +65,9 @@ class BackButtonText extends Ion {
'' +
'' +
'
',
+ host: {
+ '[hidden]': '_hidden'
+ },
directives: [BackButton, BackButtonText, Icon]
})
export class Navbar extends ToolbarBase {
@@ -105,6 +108,10 @@ export class Navbar extends ToolbarBase {
this.app.setTitle(this.getTitleText());
}
+ setHidden(isHidden) {
+ this._hidden = isHidden
+ }
+
}
@@ -118,9 +125,13 @@ export class Navbar extends ToolbarBase {
})
export class NavbarTemplate {
constructor(
- @Optional() viewCtrl: ViewController,
- @Optional() templateRef: TemplateRef
+ viewContainerRef: ViewContainerRef,
+ templateRef: TemplateRef,
+ @Optional() viewCtrl: ViewController
) {
- viewCtrl && viewCtrl.setNavbarTemplateRef(templateRef);
+ if (viewCtrl) {
+ viewCtrl.setNavbarTemplateRef(templateRef);
+ viewCtrl.setNavbarViewRef(viewContainerRef);
+ }
}
}
diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts
index 9c599e1074..8ee53827db 100644
--- a/ionic/components/nav/nav-controller.ts
+++ b/ionic/components/nav/nav-controller.ts
@@ -1,7 +1,6 @@
import {Compiler, ElementRef, Injector, provide, NgZone, DynamicComponentLoader, AppViewManager, Renderer} from 'angular2/angular2';
import {Ion} from '../ion';
-import {makeComponent} from '../../config/decorators';
import {IonicApp} from '../app/app';
import {Config} from '../../config/config';
import {ViewController} from './view-controller';
@@ -445,6 +444,9 @@ export class NavController extends Ion {
if (!opts.animation) {
opts.animation = this.config.get('viewTransition');
}
+ if (this.config.get('animate') === false) {
+ opts.animate = false;
+ }
// wait for the new view to complete setup
enteringView.stage(() => {
@@ -508,34 +510,51 @@ export class NavController extends Ion {
}
- /**
- * @private
- * TODO
- */
- compileView(componentType) {
- // create a new ion-view annotation
- let viewComponentType = makeComponent(componentType, {
- selector: 'ion-view',
- host: {
- '[class.pane-view]': '_paneView'
- }
- });
-
- // compile the Component
- return this._compiler.compileInHost(viewComponentType);
- }
-
- /**
- * @private
- * TODO
- */
- loadNextToAnchor(type, location, viewCtrl) {
+ loadPage(viewCtrl, navbarContainerRef, done) {
let providers = this.providers.concat(Injector.resolve([
provide(ViewController, {useValue: viewCtrl}),
provide(NavParams, {useValue: viewCtrl.params})
]));
- return this._loader.loadNextToLocation(type, location, providers);
+ this._loader.loadIntoLocation(viewCtrl.componentType, this.elementRef, 'contents', providers).then(componentRef => {
+
+ viewCtrl.addDestroy(() => {
+ componentRef.dispose();
+ });
+
+ // a new ComponentRef has been created
+ // set the ComponentRef's instance to this ViewController
+ viewCtrl.setInstance(componentRef.instance);
+
+ // remember the ElementRef to the ion-page elementRef that was just created
+ viewCtrl.setPageRef(componentRef.location);
+
+ if (!navbarContainerRef) {
+ navbarContainerRef = viewCtrl.getNavbarViewRef();
+ }
+
+ let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
+ if (navbarContainerRef && navbarTemplateRef) {
+ let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef);
+
+ viewCtrl.addDestroy(() => {
+ let index = navbarContainerRef.indexOf(navbarView);
+ if (index > -1) {
+ navbarContainerRef.remove(index);
+ }
+ });
+ }
+
+ if (this._views.length === 1) {
+ this._zone.runOutsideAngular(() => {
+ setTimeout(() => {
+ this.renderer.setElementClass(this.elementRef, 'has-views', true);
+ }, 200);
+ });
+ }
+
+ done(viewCtrl);
+ });
}
/**
@@ -543,6 +562,7 @@ export class NavController extends Ion {
* TODO
*/
swipeBackStart() {
+ return;
if (!this.app.isEnabled() || !this.canSwipeBack()) {
return;
}
@@ -594,6 +614,7 @@ export class NavController extends Ion {
* @param {TODO} progress TODO
*/
swipeBackProgress(value) {
+ return;
if (this._sbTrans) {
// continue to disable the app while actively dragging
this.app.setEnabled(false, 4000);
@@ -610,6 +631,7 @@ export class NavController extends Ion {
* @param {number} rate How fast it closes
*/
swipeBackEnd(completeSwipeBack, rate) {
+ return;
if (!this._sbTrans) return;
// disables the app during the transition
@@ -672,6 +694,7 @@ export class NavController extends Ion {
* TODO
*/
_sbComplete() {
+ return;
if (this.canSwipeBack()) {
// it is possible to swipe back
@@ -789,16 +812,6 @@ export class NavController extends Ion {
});
}
- addHasViews() {
- if (this._views.length === 1) {
- this._zone.runOutsideAngular(() => {
- setTimeout(() => {
- this.renderer.setElementClass(this.elementRef, 'has-views', true);
- }, 200);
- });
- }
- }
-
/**
* TODO
* @param {TODO} nbContainer TODO
diff --git a/ionic/components/nav/nav.ts b/ionic/components/nav/nav.ts
index f2bf31712d..d1106fc800 100644
--- a/ionic/components/nav/nav.ts
+++ b/ionic/components/nav/nav.ts
@@ -130,18 +130,10 @@ import {NavController} from './nav-controller';
defaultInputs: {
'swipeBackEnabled': true
},
- template: '',
- directives: [forwardRef(() => NavPaneAnchor)]
+ template: ''
})
export class Nav extends NavController {
- /**
- * TODO
- * @param {NavController} hostNavCtrl TODO
- * @param {Injector} injector TODO
- * @param {ElementRef} elementRef TODO
- * @param {NgZone} zone TODO
- */
constructor(
@Optional() hostNavCtrl: NavController,
app: IonicApp,
@@ -154,7 +146,6 @@ export class Nav extends NavController {
renderer: Renderer
) {
super(hostNavCtrl, app, config, elementRef, compiler, loader, viewManager, zone, renderer);
- this.panes = [];
}
/**
@@ -171,263 +162,7 @@ export class Nav extends NavController {
}
// default the swipe back to be enabled
- let isSwipeBackEnabled = (this.swipeBackEnabled || '').toString() !== 'false';
- this.isSwipeBackEnabled( isSwipeBackEnabled );
- }
-
- /**
- * @private
- * TODO
- * @param {TODO} componentType TODO
- * @param {TODO} hostProtoViewRef TODO
- * @param {TODO} viewCtrl TODO
- * @param {Function} done TODO
- * @return {TODO} TODO
- */
- loadContainer(componentType, hostProtoViewRef, viewCtrl, done) {
- // this gets or creates the Pane which similar nav items live in
- // Nav items with just a navbar/content would all use the same Pane
- // Tabs and view's without a navbar would get a different Panes
- let structure = this.getStructure(hostProtoViewRef);
-
- if (structure.tabs) {
- // the component being loaded is an
- // Tabs is essentially a pane, cuz it has its own navbar and content containers
- this.loadNextToAnchor(componentType, this.anchorElementRef(), viewCtrl).then(componentRef => {
-
- componentRef.instance._paneView = true;
-
- viewCtrl.disposals.push(() => {
- componentRef.dispose();
- });
-
- viewCtrl.onReady().then(() => {
- done();
- });
-
- });
-
- } else {
- // normal ion-view going into pane
- this.getPane(structure, viewCtrl, (pane) => {
- // add the content of the view into the pane's content area
- this.loadNextToAnchor(componentType, pane.contentAnchorRef, viewCtrl).then(componentRef => {
-
- viewCtrl.disposals.push(() => {
- componentRef.dispose();
-
- // remove the pane if there are no view items left
- pane.totalViews--;
- if (pane.totalViews === 0) {
- pane.dispose && pane.dispose();
- }
- });
-
- // count how many ViewControllers are in this pane
- pane.totalViews++;
-
- // a new ComponentRef has been created
- // set the ComponentRef's instance to this ViewController
- viewCtrl.setInstance(componentRef.instance);
-
- // remember the ElementRef to the content that was just created
- viewCtrl.setContentRef(componentRef.location);
-
- // get the NavController's container for navbars, which is
- // the place this NavController will add each ViewController's navbar
- let navbarContainerRef = pane.navbarContainerRef;
-
- // get this ViewController's navbar TemplateRef, which may not
- // exist if the ViewController's template didn't have an
- let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
-
- // create the navbar view if the pane has a navbar container, and the
- // ViewController's instance has a navbar TemplateRef to go to inside of it
- if (navbarContainerRef && navbarTemplateRef) {
- let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
-
- viewCtrl.disposals.push(() => {
- let index = navbarContainerRef.indexOf(navbarView);
- if (index > -1) {
- navbarContainerRef.remove(index);
- }
- });
- }
-
- this.addHasViews();
-
- done();
- });
-
- });
- }
- }
-
- /**
- * @private
- * TODO
- * @param {TODO} structure TODO
- * @param {TODO} viewCtrl TODO
- * @param {Function} done TODO
- * @return {TODO} TODO
- */
- getPane(structure, viewCtrl, done) {
- let pane = this.panes[this.panes.length - 1];
-
- if (pane && pane.navbar === structure.navbar) {
- // the last pane's structure is the same as the one
- // this ViewController will need, so reuse it
- done(pane);
-
- } else {
- // create a new nav pane
- this._loader.loadNextToLocation(Pane, this.anchorElementRef(), this.bindings).then(componentRef => {
-
- // get the pane reference
- pane = this.newPane;
- this.newPane = null;
-
- pane.showNavbar(structure.navbar);
- pane.dispose = () => {
- componentRef.dispose();
- this.panes.splice(this.panes.indexOf(pane), 1);
- };
-
- this.panes.push(pane);
-
- done(pane);
-
- }, loaderErr => {
- console.error(loaderErr);
-
- }).catch(err => {
- console.error(err);
- });
-
- }
- }
- /**
- * @private
- * TODO
- * @param {TODO} pane TODO
- * @return {TODO} TODO
- */
- addPane(pane) {
- this.newPane = pane;
- }
-
- /**
- * @private
- * TODO
- * @param {TODO} componentProtoViewRef TODO
- * @return {TODO} TODO
- */
- getStructure(componentProtoViewRef) {
- let templateCmds = componentProtoViewRef._protoView.templateCmds;
- let compiledTemplateData, directives;
- let i, ii, j, jj, k, kk;
-
- for (i = 0, ii = templateCmds.length; i < ii; i++) {
- if (templateCmds[i].template) {
- compiledTemplateData = templateCmds[i].template.getData(templateCmds[i].templateId);
- if (compiledTemplateData) {
- for (j = 0, jj = compiledTemplateData.commands.length; j < jj; j++) {
- directives = compiledTemplateData.commands[j].directives;
-
- if (directives && (kk = directives.length)) {
-
- for (k = 0; k < kk; k++) {
-
- if (directives[k].name == 'NavbarTemplate') {
- return { navbar: true };
- }
-
- if (directives[k].name == 'Tabs') {
- return { tabs: true };
- }
-
- }
-
- }
-
- }
- }
- }
- }
-
- return {};
- }
-
-}
-
-/**
- * @private
- */
-@Directive({selector: 'template[pane-anchor]'})
-class NavPaneAnchor {
- constructor(@Host() nav: Nav, elementRef: ElementRef) {
- nav.anchorElementRef(elementRef);
- }
-}
-
-/**
- * @private
- */
-@Directive({selector: 'template[navbar-anchor]'})
-class NavBarAnchor {
- constructor(
- @Host() @Inject(forwardRef(() => Pane)) pane: Pane,
- viewContainerRef: ViewContainerRef
- ) {
- pane.navbarContainerRef = viewContainerRef;
- }
-}
-
-/**
- * @private
- */
-@Directive({selector: 'template[content-anchor]'})
-class ContentAnchor {
- constructor(
- @Host() @Inject(forwardRef(() => Pane)) pane: Pane,
- elementRef: ElementRef
- ) {
- pane.contentAnchorRef = elementRef;
- }
-}
-
-/**
- * @private
- */
-@Component({
- selector: 'ion-pane',
- template:
- '' +
- '' +
- '' +
- '' +
- '' +
- '',
- directives: [NavBarAnchor, ContentAnchor]
-})
-class Pane {
- constructor(
- nav: Nav,
- elementRef: ElementRef,
- renderer: Renderer
- ) {
- this.zIndex = (nav.panes.length ? nav.panes[nav.panes.length - 1].zIndex + 1 : 0);
- renderer.setElementStyle(elementRef, 'zIndex', this.zIndex);
-
- nav.addPane(this);
- this.totalViews = 0;
- this.elementRef = elementRef;
- this.renderer = renderer;
- }
-
- showNavbar(hasNavbar) {
- this.navbar = hasNavbar;
- this.renderer.setElementAttribute(this.elementRef, 'no-navbar', hasNavbar ? null : '' );
+ this.isSwipeBackEnabled( (this.swipeBackEnabled || '').toString() !== 'false' );
}
}
diff --git a/ionic/components/nav/test/basic/e2e.ts b/ionic/components/nav/test/basic/e2e.ts
index e33c933135..bf022c3ae7 100644
--- a/ionic/components/nav/test/basic/e2e.ts
+++ b/ionic/components/nav/test/basic/e2e.ts
@@ -1,16 +1,16 @@
it('should go from 1 to 2', function() {
- element(by.css('#from1To2')).click();
+ element(by.css('.e2eFrom1To2')).click();
});
it('should go from 2 to 3', function() {
- element(by.css('#from2To3')).click();
+ element(by.css('.e2eFrom2To3')).click();
});
it('should go from 3 to 2', function() {
- element(by.css('#from3To2')).click();
+ element(by.css('.e2eFrom3To2')).click();
});
it('should go from 2 to 1', function() {
- element(by.css('#from2To1')).click();
+ element(by.css('.e2eFrom2To1')).click();
});
diff --git a/ionic/components/nav/test/basic/index.ts b/ionic/components/nav/test/basic/index.ts
index 6115f188a3..8b88fc2dba 100644
--- a/ionic/components/nav/test/basic/index.ts
+++ b/ionic/components/nav/test/basic/index.ts
@@ -6,7 +6,7 @@ import {NavParams, NavController} from 'ionic/ionic';
@Page({
template: `
- FriendsEnemies
+ {{title}}
@@ -16,14 +16,15 @@ import {NavParams, NavController} from 'ionic/ionic';
{{title}}
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
`
})
@@ -36,19 +37,27 @@ class FirstPage {
this.nav = nav;
this.title = 'First Page';
- this.pushPage = SecondPage;
+ this.pushPage = FullPage;
}
setViews() {
let items = [
- ThirdPage
+ PrimaryHeaderPage
];
this.nav.setViews(items);
}
- push() {
- this.nav.push(SecondPage, { id: 8675309, myData: [1,2,3,4] } );
+ pushPrimaryHeaderPage() {
+ this.nav.push(PrimaryHeaderPage);
+ }
+
+ pushFullPage() {
+ this.nav.push(FullPage, { id: 8675309, myData: [1,2,3,4] } );
+ }
+
+ pushAnother() {
+ this.nav.push(AnotherPage);
}
}
@@ -56,42 +65,45 @@ class FirstPage {
@Page({
template: `
- Second page
+ Full page
This page does not have a nav bar!
-
-
-
-
-
+
+
+
+
+
+
`
})
-class SecondPage {
+class FullPage {
constructor(
nav: NavController,
params: NavParams
) {
this.nav = nav;
this.params = params;
-
- console.log('Second page params:', params);
}
setViews() {
let items = [
FirstPage,
- ThirdPage
+ PrimaryHeaderPage
];
this.nav.setViews(items);
}
- pop() {
- this.nav.pop();
+ pushPrimaryHeaderPage() {
+ this.nav.push(PrimaryHeaderPage);
}
- push() {
- this.nav.push(ThirdPage);
+ pushAnother() {
+ this.nav.push(AnotherPage);
+ }
+
+ pushFirstPage() {
+ this.nav.push(FirstPage);
}
}
@@ -99,29 +111,32 @@ class SecondPage {
@Page({
template: `
- Third Page Header
+
+ Primary Color Page Header
+
-
-
+
+
+
`
})
-class ThirdPage {
+class PrimaryHeaderPage {
constructor(
nav: NavController
) {
this.nav = nav
}
- push() {
- this.nav.push(FourthPage);
+ pushAnother() {
+ this.nav.push(AnotherPage);
}
- pop() {
- this.nav.pop()
+ pushFullPage() {
+ this.nav.push(FullPage, { id: 8675309, myData: [1,2,3,4] } );
}
insert() {
@@ -137,28 +152,40 @@ class ThirdPage {
@Page({
template: `
- Fourth Page Header
+
+ Another Page Header
+
-
-
-
+
+
+
+
`
})
-class FourthPage {
+class AnotherPage {
constructor(
nav: NavController
) {
this.nav = nav
}
+
+ pushFullPage() {
+ this.nav.push(FullPage);
+ }
+
+ pushPrimaryHeaderPage() {
+ this.nav.push(PrimaryHeaderPage);
+ }
+
+ pushFirstPage() {
+ this.nav.push(FirstPage);
+ }
}
@App({
- template: `
-
- `,
- views: [FirstPage, SecondPage, ThirdPage]
+ template: ``
})
class E2EApp {
constructor() {
diff --git a/ionic/components/nav/view-controller.ts b/ionic/components/nav/view-controller.ts
index ef0eb72bfe..0f54bad89d 100644
--- a/ionic/components/nav/view-controller.ts
+++ b/ionic/components/nav/view-controller.ts
@@ -12,15 +12,7 @@ export class ViewController {
this.params = new NavParams(params);
this.instance = null;
this.state = 0;
- this.disposals = [];
- }
-
- setContent(content) {
- this._content = content;
- }
-
- getContent() {
- return this._content;
+ this._destroys = [];
}
/**
@@ -34,25 +26,18 @@ export class ViewController {
return done();
}
- // compile the component and create a ProtoViewRef
- navCtrl.compileView(this.componentType).then(hostProtoViewRef => {
+ // get the pane the NavController wants to use
+ // the pane is where all this content will be placed into
+ navCtrl.loadPage(this, null, () => {
- if (this.shouldDestroy) return done();
-
- // get the pane the NavController wants to use
- // the pane is where all this content will be placed into
- navCtrl.loadContainer(this.componentType, hostProtoViewRef, this, () => {
-
- // this ViewController instance has finished loading
- try {
- this.loaded();
- } catch (e) {
- console.error(e);
- }
-
- done();
- });
+ // this ViewController instance has finished loading
+ try {
+ this.loaded();
+ } catch (e) {
+ console.error(e);
+ }
+ done();
});
}
@@ -87,55 +72,66 @@ export class ViewController {
return this.index === 0;
}
+ addDestroy(destroyFn) {
+ this._destroys.push(destroyFn);
+ }
+
/**
* TODO
*/
destroy() {
- for (let i = 0; i < this.disposals.length; i++) {
- this.disposals[i]();
+ for (let i = 0; i < this._destroys.length; i++) {
+ this._destroys[i]();
}
+ this._destroys = [];
}
- /**
- * @private
- */
setNavbarTemplateRef(templateRef) {
this._nbTmpRef = templateRef;
}
- /**
- * @private
- */
getNavbarTemplateRef() {
return this._nbTmpRef;
}
- /**
- * TODO
- * @returns {TODO} TODO
- */
- setContentRef(contentElementRef) {
- this._cntRef = contentElementRef;
+ getNavbarViewRef() {
+ return this._nbVwRef;
+ }
+
+ setNavbarViewRef(viewContainerRef) {
+ this._nbVwRef = viewContainerRef;
+ }
+
+ setPageRef(elementRef) {
+ this._pgRef = elementRef;
+ }
+
+ pageRef() {
+ return this._pgRef;
+ }
+
+ setContentRef(elementRef) {
+ this._cntRef = elementRef;
}
- /**
- * TODO
- * @returns {TODO} TODO
- */
contentRef() {
return this._cntRef;
}
- setNavbar(navbarView) {
- this._nbVw = navbarView;
+ setContent(directive) {
+ this._cntDir = directive;
+ }
+
+ getContent() {
+ return this._cntDir;
+ }
+
+ setNavbar(directive) {
+ this._nbDir = directive;
}
- /**
- * TODO
- * @returns {TODO} TODO
- */
getNavbar() {
- return this._nbVw;
+ return this._nbDir;
}
/**
@@ -263,18 +259,8 @@ export class ViewController {
}
domCache(isActiveView, isPreviousView) {
- let renderInDom = (isActiveView || isPreviousView);
-
- let contentRef = this.contentRef();
- if (contentRef) {
- // the active view, and the previous view should have the 'show-view' css class
- // all others, like a cached page 2 back, should now have 'show-view' so it's not rendered
- contentRef.nativeElement.classList[renderInDom ? 'add' : 'remove' ]('show-view');
- }
-
- let navbarRef = this.getNavbar();
- if (navbarRef) {
- navbarRef.elementRef.nativeElement.classList[renderInDom ? 'add' : 'remove' ]('show-navbar');
+ if (this.instance) {
+ this.instance._hidden = (!isActiveView && !isPreviousView);
}
}
diff --git a/ionic/components/overlay/overlay-controller.ts b/ionic/components/overlay/overlay-controller.ts
index afa679830f..e037caa5ca 100644
--- a/ionic/components/overlay/overlay-controller.ts
+++ b/ionic/components/overlay/overlay-controller.ts
@@ -1,6 +1,7 @@
import {Component, NgZone, Injectable, Renderer} from 'angular2/angular2';
import {IonicApp} from '../app/app';
+import {Config} from '../../config/config';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
@@ -8,8 +9,9 @@ import * as util from 'ionic/util';
@Injectable()
export class OverlayController {
- constructor(app: IonicApp, zone: NgZone, renderer: Renderer) {
+ constructor(app: IonicApp, config: Config, zone: NgZone, renderer: Renderer) {
this.app = app;
+ this.config = config;
this.zone = zone;
this.renderer = renderer;
this.refs = [];
@@ -54,6 +56,9 @@ export class OverlayController {
instance.onPageWillEnter && instance.onPageWillEnter();
let animation = Animation.create(ref.location.nativeElement, opts.enterAnimation);
+ if (this.config.get('animate') === false) {
+ animation.duration(0);
+ }
animation.before.addClass('show-overlay');
this.app.setEnabled(false, animation.duration());
@@ -95,6 +100,9 @@ export class OverlayController {
instance.onPageWillUnload && instance.onPageWillUnload();
let animation = Animation.create(ref.location.nativeElement, opts.leaveAnimation);
+ if (this.config.get('animate') === false) {
+ animation.duration(0);
+ }
animation.after.removeClass('show-overlay');
this.app.setEnabled(false, animation.duration());
diff --git a/ionic/components/search-bar/test/floating/e2e.ts b/ionic/components/search-bar/test/floating/e2e.ts
index 005c76d784..d94aca112f 100644
--- a/ionic/components/search-bar/test/floating/e2e.ts
+++ b/ionic/components/search-bar/test/floating/e2e.ts
@@ -15,15 +15,11 @@ it('custom cancel button should focus', function() {
element(by.css('.e2eCustomCancelButtonFloatingSearchBar input')).sendKeys("DD");
});
-it('custom cancel button long text should focus', function() {
- element(by.css('.e2eCustomCancelButtonLongTextFloatingSearchBar input')).sendKeys("EE");
-});
-
it('custom cancel action should focus', function() {
element(by.css('.e2eCustomCancelActionFloatingSearchBar input')).sendKeys("FF");
});
-// TODO - this test will work on iOS but fail on Android
+// TODO - this test will work on iOS but fail on Android
// it('custom cancel action should alert', function() {
// element(by.css('.e2eCustomCancelActionFloatingSearchBar .search-bar-cancel')).click();
// });
diff --git a/ionic/components/search-bar/test/floating/main.html b/ionic/components/search-bar/test/floating/main.html
index 550270944a..a9390091ed 100644
--- a/ionic/components/search-bar/test/floating/main.html
+++ b/ionic/components/search-bar/test/floating/main.html
@@ -11,9 +11,6 @@
Search - Custom Cancel Button
- Search - Custom Cancel Button Long
-
-
Search - Custom Cancel Action
diff --git a/ionic/components/segment/test/basic/e2e.ts b/ionic/components/segment/test/basic/e2e.ts
index c941f0bef6..06d1d6bb26 100644
--- a/ionic/components/segment/test/basic/e2e.ts
+++ b/ionic/components/segment/test/basic/e2e.ts
@@ -1,16 +1,10 @@
-it('friends should be selected', function() {
+it('friends and standard should be selected', function() {
element(by.css('.e2eSegmentFriends')).click();
+ element(by.css('.e2eSegmentStandard')).click();
});
-it('standard should be selected', function() {
- element(by.css('.e2eSegmentStandard')).click();
-});
-
-it('model c should be selected', function() {
+it('model c and top grossing should be selected', function() {
element(by.css('.e2eSegmentModelC')).click();
-});
-
-it('top grossing should be selected', function() {
- element(by.css('.e2eSegmentTopGrossing')).click();
+ element(by.css('.e2eSegmentTopGrossing')).click();
});
diff --git a/ionic/components/tabs/tab.ts b/ionic/components/tabs/tab.ts
index 9c9e334fd2..135e488cef 100644
--- a/ionic/components/tabs/tab.ts
+++ b/ionic/components/tabs/tab.ts
@@ -1,4 +1,4 @@
-import {Component, Directive, Host, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, forwardRef, NgZone, Renderer} from 'angular2/angular2';
+import {Component, Directive, Host, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, NgZone, Renderer} from 'angular2/angular2';
import {IonicApp} from '../app/app';
import {Config} from '../../config/config';
@@ -64,8 +64,7 @@ import {Tabs} from './tabs';
'[class.show-tab]': 'isSelected',
'role': 'tabpanel'
},
- template: '',
- directives: [forwardRef(() => TabContentAnchor)]
+ template: ''
})
export class Tab extends NavController {
@@ -83,91 +82,71 @@ export class Tab extends NavController {
// A Tab is a NavController for its child pages
super(tabs, app, config, elementRef, compiler, loader, viewManager, zone, renderer);
this.tabs = tabs;
-
this._isInitial = tabs.add(this);
}
onInit() {
- console.debug('Tab onInit', this.getIndex());
+ console.debug('Tab onInit', this.index);
if (this._isInitial) {
this.tabs.select(this);
} else if (this.tabs.preloadTabs) {
- // setTimeout(() => {
- // this.load(() => {
- // console.debug('preloaded tab', this.getIndex());
- // });
- // }, 500 * this.getIndex());
+ setTimeout(() => {
+ this.load(() => {
+ console.debug('preloaded tab', this.index);
+ this.hideNavbars(true);
+ });
+ }, 500 * this.index);
}
}
- load(callback) {
+ load(done) {
if (!this._loaded && this.root) {
let opts = {
animate: false
};
- this.push(this.root, null, opts).then(callback);
+ this.push(this.root, null, opts).then(done);
this._loaded = true;
} else {
- callback();
+ done();
}
}
- loadContainer(componentType, hostProtoViewRef, viewCtrl, done) {
+ loadPage(viewCtrl, navbarContainerRef, done) {
+ // by default a page's navbar goes into the shared tab's navbar section
+ navbarContainerRef = this.tabs.navbarContainerRef;
- this.loadNextToAnchor(componentType, this.contentAnchorRef, viewCtrl).then(componentRef => {
+ let isTabSubPage = (this.tabs.subPages && viewCtrl.index > 0);
+ if (isTabSubPage) {
+ // a subpage, that's not the first index
+ // should not use the shared tabs navbar section, but use it's own
+ navbarContainerRef = null;
+ }
- viewCtrl.disposals.push(() => {
- componentRef.dispose();
- });
-
- // a new ComponentRef has been created
- // set the ComponentRef's instance to this ViewController
- viewCtrl.setInstance(componentRef.instance);
-
- // remember the ElementRef to the content that was just created
- viewCtrl.setContentRef(componentRef.location);
-
- // get the NavController's container for navbars, which is
- // the place this NavController will add each ViewController's navbar
- let navbarContainerRef = this.tabs.navbarContainerRef;
-
- // get this ViewController's navbar TemplateRef, which may not
- // exist if the ViewController's template didn't have an
- let navbarTemplateRef = viewCtrl.getNavbarTemplateRef();
-
- // create the navbar view if the pane has a navbar container, and the
- // ViewController's instance has a navbar TemplateRef to go to inside of it
- if (navbarContainerRef && navbarTemplateRef) {
- let navbarView = navbarContainerRef.createEmbeddedView(navbarTemplateRef, -1);
-
- viewCtrl.disposals.push(() => {
- let index = navbarContainerRef.indexOf(navbarView);
- if (index > -1) {
- navbarContainerRef.remove(index);
- }
- });
+ super.loadPage(viewCtrl, navbarContainerRef, () => {
+ if (viewCtrl.instance) {
+ viewCtrl.instance._tabSubPage = isTabSubPage;
}
-
- this.addHasViews();
-
done();
});
-
}
- getIndex() {
+ setSelected(isSelected) {
+ this.isSelected = isSelected;
+ this.hideNavbars(!isSelected);
+ }
+
+ hideNavbars(shouldHideNavbars) {
+ this._views.forEach(viewCtrl => {
+ let navbar = viewCtrl.getNavbar();
+ navbar && navbar.setHidden(shouldHideNavbars);
+ });
+ }
+
+ get index() {
return this.tabs.getIndex(this);
}
}
-
-
-@Directive({selector: 'template[content-anchor]'})
-class TabContentAnchor {
- constructor(@Host() tab: Tab, elementRef: ElementRef) {
- tab.contentAnchorRef = elementRef;
- }
-}
diff --git a/ionic/components/tabs/tabs.scss b/ionic/components/tabs/tabs.scss
index 003493df98..a85f7093e6 100644
--- a/ionic/components/tabs/tabs.scss
+++ b/ionic/components/tabs/tabs.scss
@@ -46,10 +46,6 @@ ion-tabs > ion-navbar-section {
order: $flex-order-tab-bar-navbar;
}
-ion-tabs ion-navbar.toolbar.deselected-tab {
- display: none;
-}
-
ion-tab-bar-section {
position: relative;
order: $flex-order-tab-bar-bottom;
@@ -161,4 +157,3 @@ tab-highlight {
[tab-bar-icons=hide] .tab-button-icon {
display: none;
}
-
diff --git a/ionic/components/tabs/tabs.ts b/ionic/components/tabs/tabs.ts
index 2cdeaeae13..389d3f8b33 100644
--- a/ionic/components/tabs/tabs.ts
+++ b/ionic/components/tabs/tabs.ts
@@ -1,4 +1,4 @@
-import {Directive, ElementRef, Optional, Host, NgFor, forwardRef, ViewContainerRef} from 'angular2/angular2';
+import {Directive, ElementRef, Optional, Host, NgFor, NgIf, forwardRef, ViewContainerRef} from 'angular2/angular2';
import {Ion} from '../ion';
import {IonicApp} from '../app/app';
@@ -71,7 +71,7 @@ import {Icon} from '../icon/icon';
'' +
'' +
'' +
- '' +
+ '' +
'' +
'{{t.tabTitle}}' +
'' +
@@ -84,6 +84,7 @@ import {Icon} from '../icon/icon';
directives: [
Icon,
NgFor,
+ NgIf,
forwardRef(() => TabButton),
forwardRef(() => TabHighlight),
forwardRef(() => TabNavBarAnchor)
@@ -108,18 +109,22 @@ export class Tabs extends Ion {
super(elementRef, config);
this.app = app;
this.preload = config.get('preloadTabs');
+ this.subPages = config.get('tabSubPages');
// collection of children "Tab" instances, which extends NavController
- this._tabs = [];
+ this.tabs = [];
// 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._ready = new Promise(res => { this._isReady = res; });
+ viewCtrl.setContent(this);
+ viewCtrl.setContentRef(elementRef);
+ // TODO: improve how this works, probably not use promises here
+ this.readyPromise = new Promise(res => { this.isReady = res; });
viewCtrl.onReady = () => {
- return this._ready;
+ return this.readyPromise;
};
}
}
@@ -131,9 +136,9 @@ export class Tabs extends Ion {
tab.id = ++_tabIds;
tab.btnId = 'tab-' + tab.id;
tab.panelId = 'tabpanel-' + tab.id;
- this._tabs.push(tab);
+ this.tabs.push(tab);
- return (this._tabs.length === 1);
+ return (this.tabs.length === 1);
}
/**
@@ -142,40 +147,25 @@ export class Tabs extends Ion {
* @returns {TODO} TODO
*/
select(tabOrIndex) {
- let selectedTab = null;
-
- if (typeof tabOrIndex === 'number') {
- selectedTab = this.getByIndex(tabOrIndex);
-
- } else {
- selectedTab = tabOrIndex;
- }
-
- if (!selectedTab || !this.app.isEnabled()) {
+ let selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
+ if (!selectedTab) {
return Promise.reject();
}
+ console.debug('select tab', selectedTab.id);
+
let deselectedTab = this.getSelected();
if (selectedTab === deselectedTab) {
// no change
- return this._touchActive(selectedTab);
+ return this.touchActive(selectedTab);
}
- console.debug('select tab', selectedTab.id);
-
selectedTab.load(() => {
- this._isReady && this._isReady();
+ this.isReady && this.isReady();
- this._tabs.forEach(tab => {
- tab.isSelected = (tab === selectedTab);
-
- tab._views.forEach(viewCtrl => {
- let navbarRef = viewCtrl.navbarRef();
- if (navbarRef) {
- navbarRef.nativeElement.classList[tab.isSelected ? 'remove': 'add']('deselected-tab');
- }
- });
+ this.tabs.forEach(tab => {
+ tab.setSelected(tab === selectedTab);
});
this.highlight && this.highlight.select(selectedTab);
@@ -188,23 +178,23 @@ export class Tabs extends Ion {
* @returns {TODO} TODO
*/
getByIndex(index) {
- if (index < this._tabs.length && index > -1) {
- return this._tabs[index];
+ if (index < this.tabs.length && index > -1) {
+ return this.tabs[index];
}
return null;
}
getSelected() {
- for (let i = 0; i < this._tabs.length; i++) {
- if (this._tabs[i].isSelected) {
- return this._tabs[i];
+ for (let i = 0; i < this.tabs.length; i++) {
+ if (this.tabs[i].isSelected) {
+ return this.tabs[i];
}
}
return null;
}
getIndex(tab) {
- return this._tabs.indexOf(tab);
+ return this.tabs.indexOf(tab);
}
/**
@@ -212,10 +202,8 @@ export class Tabs extends Ion {
* "Touch" the active tab, either going back to the root view of the tab
* or scrolling the tab to the top
*/
- _touchActive(tab) {
- let stateLen = tab.length();
-
- if(stateLen > 1) {
+ touchActive(tab) {
+ if (tab.length() > 1) {
// Pop to the root view
return tab.popToRoot();
}
@@ -230,7 +218,6 @@ let _tabIds = -1;
/**
* @private
- * TODO
*/
@Directive({
selector: '.tab-button',
@@ -243,17 +230,15 @@ let _tabIds = -1;
'[class.has-icon]': 'hasIcon',
'[class.has-title-only]': 'hasTitleOnly',
'[class.icon-only]': 'hasIconOnly',
- '(click)': 'onClick($event)',
+ '[class.disable-hover]': 'disHover',
+ '(click)': 'onClick()',
}
})
class TabButton extends Ion {
constructor(@Host() tabs: Tabs, config: Config, elementRef: ElementRef) {
super(elementRef, config);
this.tabs = tabs;
-
- if (config.get('hoverCSS') === false) {
- elementRef.nativeElement.classList.add('disable-hover');
- }
+ this.disHover = (config.get('hoverCSS') === false);
}
onInit() {
@@ -264,16 +249,14 @@ class TabButton extends Ion {
this.hasIconOnly = (this.hasIcon && !this.hasTitle);
}
- onClick(ev) {
- ev.stopPropagation();
- ev.preventDefault();
+ onClick() {
this.tabs.select(this.tab);
}
}
+
/**
* @private
- * TODO
*/
@Directive({
selector: 'tab-highlight'
@@ -306,14 +289,10 @@ class TabHighlight {
/**
* @private
- * TODO
*/
@Directive({selector: 'template[navbar-anchor]'})
class TabNavBarAnchor {
- constructor(
- @Host() tabs: Tabs,
- viewContainerRef: ViewContainerRef
- ) {
+ constructor(@Host() tabs: Tabs, viewContainerRef: ViewContainerRef) {
tabs.navbarContainerRef = viewContainerRef;
}
}
diff --git a/ionic/components/tabs/test/tab-bar-scenarios/index.ts b/ionic/components/tabs/test/tab-bar-scenarios/index.ts
index 43aed36502..834efa41bb 100644
--- a/ionic/components/tabs/test/tab-bar-scenarios/index.ts
+++ b/ionic/components/tabs/test/tab-bar-scenarios/index.ts
@@ -5,3 +5,5 @@ import {App} from 'ionic/ionic';
templateUrl: 'main.html'
})
class E2EApp {}
+
+document.body.innerHTML += ''
diff --git a/ionic/components/tabs/test/tab-bar-scenarios/main.html b/ionic/components/tabs/test/tab-bar-scenarios/main.html
index 3db2d1f21c..6c2e11d34a 100644
--- a/ionic/components/tabs/test/tab-bar-scenarios/main.html
+++ b/ionic/components/tabs/test/tab-bar-scenarios/main.html
@@ -59,11 +59,3 @@
-
-
-
diff --git a/ionic/components/tabs/test/tab-bar-scenarios/styles.css b/ionic/components/tabs/test/tab-bar-scenarios/styles.css
new file mode 100644
index 0000000000..b5b6cbf640
--- /dev/null
+++ b/ionic/components/tabs/test/tab-bar-scenarios/styles.css
@@ -0,0 +1,12 @@
+
+ion-tabs {
+ position: relative;
+ top: auto;
+ height: auto;
+ margin-bottom: 20px;
+}
+
+ion-navbar-section,
+ion-content-section {
+ display: none !important;
+}
diff --git a/ionic/components/toolbar/modes/ios.scss b/ionic/components/toolbar/modes/ios.scss
index e6699d1bd5..f1b10aa69e 100644
--- a/ionic/components/toolbar/modes/ios.scss
+++ b/ionic/components/toolbar/modes/ios.scss
@@ -84,6 +84,7 @@ ion-title {
height: 100%;
padding: 0px 90px 1px 90px;
pointer-events: none;
+ transform: translateZ(0px);
}
.toolbar-title {
@@ -96,6 +97,7 @@ ion-title {
ion-nav-items {
flex: 1;
order: map-get($toolbar-order-ios, primary);
+ transform: translateZ(0px);
}
ion-nav-items[secondary] {
diff --git a/ionic/components/toolbar/toolbar.scss b/ionic/components/toolbar/toolbar.scss
index 9127b8d73f..1e5ca5bd15 100644
--- a/ionic/components/toolbar/toolbar.scss
+++ b/ionic/components/toolbar/toolbar.scss
@@ -75,7 +75,6 @@ ion-title {
order: map-get($toolbar-order, title);
display: flex;
align-items: center;
- transform: translateZ(0px);
}
.toolbar-title {
@@ -109,7 +108,6 @@ ion-title {
ion-nav-items {
display: block;
margin: 0 0.2rem;
- transform: translateZ(0px);
pointer-events: none;
order: map-get($toolbar-order, primary);
}
diff --git a/ionic/config/config.ts b/ionic/config/config.ts
index 7685a8d6d3..c26b0be1b7 100644
--- a/ionic/config/config.ts
+++ b/ionic/config/config.ts
@@ -127,6 +127,11 @@ export class Config {
let configObj = null;
if (this._platform) {
+ let queryStringValue = this._platform.query('ionic' + key.toLowerCase());
+ if (isDefined(queryStringValue)) {
+ return this._c[key] = (queryStringValue === 'true' ? true : queryStringValue === 'false' ? false : queryStringValue);
+ }
+
// check the platform settings object for this value
// loop though each of the active platforms
diff --git a/ionic/config/decorators.ts b/ionic/config/decorators.ts
index 4095bbb0ba..e6b1f300af 100644
--- a/ionic/config/decorators.ts
+++ b/ionic/config/decorators.ts
@@ -1,18 +1,9 @@
-import {Component, Directive, View, bootstrap} from 'angular2/angular2'
+import {Component, bootstrap} from 'angular2/angular2'
import * as util from 'ionic/util';
import {ionicProviders} from './bootstrap';
import {IONIC_DIRECTIVES} from './directives';
-/**
- * @private
- */
-class PageImpl extends View {
- constructor(args = {}) {
- args.directives = (args.directives || []).concat(IONIC_DIRECTIVES);
- super(args);
- }
-}
/**
* _For more information on how pages are created, see the [NavController API
@@ -72,30 +63,30 @@ class PageImpl extends View {
* you may see these tags if you inspect your markup, you don't need to include
* them in your templates.
*/
-export function Page(args) {
+export function Page(config={}) {
return function(cls) {
+ config.selector = 'ion-page';
+ config.directives = config.directives ? config.directives.concat(IONIC_DIRECTIVES) : IONIC_DIRECTIVES;
+ config.host = config.host || {};
+ config.host['[hidden]'] = '_hidden';
+ config.host['[class.tab-subpage]'] = '_tabSubPage';
var annotations = Reflect.getMetadata('annotations', cls) || [];
- annotations.push(new PageImpl(args));
+ annotations.push(new Component(config));
Reflect.defineMetadata('annotations', annotations, cls);
return cls;
}
}
-/**
- * TODO
- */
+
export function ConfigComponent(config) {
return function(cls) {
- return makeComponent(cls, appendConfig(cls, config));
+ var annotations = Reflect.getMetadata('annotations', cls) || [];
+ annotations.push(new Component(config));
+ Reflect.defineMetadata('annotations', annotations, cls);
+ return cls;
}
}
-export function makeComponent(cls, config) {
- var annotations = Reflect.getMetadata('annotations', cls) || [];
- annotations.push(new Component(config));
- Reflect.defineMetadata('annotations', annotations, cls);
- return cls;
-}
function appendConfig(cls, config) {
config.host = config.host || {};
diff --git a/ionic/config/modes.ts b/ionic/config/modes.ts
index 7f62e076ba..aa40a4597d 100644
--- a/ionic/config/modes.ts
+++ b/ionic/config/modes.ts
@@ -48,6 +48,7 @@ Config.setModeConfig('md', {
popupPopIn: 'popup-md-pop-in',
popupPopOut: 'popup-md-pop-out',
+ tabSubPages: true,
type: 'overlay',
mdRipple: true,
});
diff --git a/ionic/config/test/config.spec.ts b/ionic/config/test/config.spec.ts
index 246b1c5d45..5f8a5bb3ff 100644
--- a/ionic/config/test/config.spec.ts
+++ b/ionic/config/test/config.spec.ts
@@ -57,6 +57,42 @@ export function run() {
expect(config.get('tabBarPlacement')).toEqual('top');
});
+ it('should get boolean value from querystring', () => {
+ let config = new Config();
+ let platform = new Platform();
+ platform.url('http://biff.com/?ionicanimate=true')
+ config.setPlatform(platform);
+ expect(config.get('animate')).toEqual(true);
+
+ config = new Config();
+ platform = new Platform();
+ platform.url('http://biff.com/?ionicanimate=false')
+ config.setPlatform(platform);
+ expect(config.get('animate')).toEqual(false);
+ });
+
+ it('should get value from case insensitive querystring key', () => {
+ let config = new Config({
+ mode: 'a'
+ });
+ let platform = new Platform();
+ platform.url('http://biff.com/?ionicConfigKey=b')
+ config.setPlatform(platform);
+
+ expect(config.get('configKey')).toEqual('b');
+ });
+
+ it('should get value from querystring', () => {
+ let config = new Config({
+ mode: 'modeA'
+ });
+ let platform = new Platform();
+ platform.url('http://biff.com/?ionicmode=modeB')
+ config.setPlatform(platform);
+
+ expect(config.get('mode')).toEqual('modeB');
+ });
+
it('should override mode platform', () => {
let config = new Config({
mode: 'modeA',
diff --git a/ionic/gestures/hammer.ts b/ionic/gestures/hammer.ts
index c9e769ff73..5c781532a1 100644
--- a/ionic/gestures/hammer.ts
+++ b/ionic/gestures/hammer.ts
@@ -165,7 +165,7 @@ function ifUndefined(val1, val2) {
*/
function addEventListeners(target, types, handler) {
each(splitStr(types), function(type) {
- console.debug('hammer addEventListener', type, target.tagName);
+ //console.debug('hammer addEventListener', type, target.tagName);
target.addEventListener(type, handler, false);
});
}
@@ -178,7 +178,7 @@ function addEventListeners(target, types, handler) {
*/
function removeEventListeners(target, types, handler) {
each(splitStr(types), function(type) {
- console.debug('hammer removeEventListener', type, target.tagName);
+ //console.debug('hammer removeEventListener', type, target.tagName);
target.removeEventListener(type, handler, false);
});
}
@@ -394,7 +394,7 @@ Input.prototype = {
* bind the events
*/
init: function() {
- console.debug('hammer Input init')
+ //console.debug('hammer Input init')
this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
diff --git a/ionic/ionic.core.scss b/ionic/ionic.core.scss
index ca6ad490ff..045b7abd6a 100644
--- a/ionic/ionic.core.scss
+++ b/ionic/ionic.core.scss
@@ -24,7 +24,6 @@
"components/button/button-icon",
"components/button/button-fab",
"components/checkbox/checkbox",
- "components/content/content",
"components/icon/icon",
"components/item/item",
"components/item/item-media",
diff --git a/ionic/platform/test/platform.spec.ts b/ionic/platform/test/platform.spec.ts
index 93b051b54b..4d77d04ae8 100644
--- a/ionic/platform/test/platform.spec.ts
+++ b/ionic/platform/test/platform.spec.ts
@@ -21,6 +21,20 @@ export function run() {
expect(platform.is('ios')).toEqual(false);
});
+ it('should get case insensitive querystring value', () => {
+ let platform = new Platform();
+ platform.url('/?KEY=value');
+
+ expect(platform.query('key')).toEqual('value');
+ });
+
+ it('should get querystring value', () => {
+ let platform = new Platform();
+ platform.url('/?key=value');
+
+ expect(platform.query('key')).toEqual('value');
+ });
+
it('should set ios via platformOverride, despite android querystring', () => {
let platform = new Platform();
platform.url('/?ionicplatform=android');
diff --git a/ionic/transitions/ios-transition.ts b/ionic/transitions/ios-transition.ts
index 9d43058b5b..b55cb5be2e 100644
--- a/ionic/transitions/ios-transition.ts
+++ b/ionic/transitions/ios-transition.ts
@@ -9,8 +9,6 @@ const OFF_RIGHT = '99.5%';
const OFF_LEFT = '-33%';
const CENTER = '0%'
const OFF_OPACITY = 0.8;
-const SHOW_NAVBAR_CSS = 'show-navbar';
-const SHOW_VIEW_CSS = 'show-view';
const SHOW_BACK_BTN_CSS = 'show-back-button';
@@ -36,29 +34,24 @@ class IOSTransition extends Animation {
// entering content
let enteringContent = new Animation(enteringView.contentRef());
- enteringContent
- .before.addClass(SHOW_VIEW_CSS)
- .before.setStyles({ zIndex: enteringView.index });
this.add(enteringContent);
if (backDirection) {
- // back direction
+ // entering content, back direction
enteringContent
.fromTo(TRANSLATEX, OFF_LEFT, CENTER)
.fromTo(OPACITY, OFF_OPACITY, 1);
} else {
- // forward direction
+ // entering content, forward direction
enteringContent
.fromTo(TRANSLATEX, OFF_RIGHT, CENTER)
.fromTo(OPACITY, 1, 1);
}
-
- // entering navbar
if (enteringHasNavbar) {
+ // entering page has a navbar
let enteringNavBar = new Animation(enteringView.navbarRef());
- enteringNavBar.before.addClass(SHOW_NAVBAR_CSS);
this.add(enteringNavBar);
let enteringTitle = new Animation(enteringView.titleRef());
@@ -76,62 +69,68 @@ class IOSTransition extends Animation {
// set properties depending on direction
if (backDirection) {
- // back direction
+ // entering navbar, back direction
enteringTitle.fromTo(TRANSLATEX, OFF_LEFT, CENTER);
if (enteringView.enableBack()) {
- enteringBackButton.before.addClass(SHOW_BACK_BTN_CSS);
+ // back direction, entering page has a back button
enteringBackButton.fadeIn();
}
} else {
- // forward direction
+ // entering navbar, forward direction
enteringTitle.fromTo(TRANSLATEX, OFF_RIGHT, CENTER);
- if (enteringView.enableBack()) {
- enteringBackButton.before.addClass(SHOW_BACK_BTN_CSS);
- enteringBackButton.fadeIn();
-
- let enteringBackBtnText = new Animation(enteringView.backBtnTextRef());
- enteringBackBtnText.fromTo(TRANSLATEX, '150px', '0px');
- enteringNavBar.add(enteringBackBtnText);
- }
-
if (leavingHasNavbar) {
- // if there is a leaving navbar, then just fade this one in
+ // entering navbar, forward direction, and there's a leaving navbar
+ // should just fade in, no sliding
enteringNavbarBg
.fromTo(TRANSLATEX, CENTER, CENTER)
.fadeIn();
} else {
- enteringNavbarBg.fromTo(TRANSLATEX, OFF_RIGHT, CENTER);
+ // entering navbar, forward direction, and there's no leaving navbar
+ // should just slide in, no fading in
+ enteringNavbarBg
+ .fromTo(TRANSLATEX, OFF_RIGHT, CENTER)
+ .fromTo(OPACITY, 1, 1);
}
+
+ if (enteringView.enableBack()) {
+ // forward direction, entering page has a back button
+ enteringBackButton
+ .before.addClass(SHOW_BACK_BTN_CSS)
+ .fadeIn();
+
+ let enteringBackBtnText = new Animation(enteringView.backBtnTextRef());
+ enteringBackBtnText.fromTo(TRANSLATEX, '100px', '0px');
+ enteringNavBar.add(enteringBackBtnText);
+ }
}
}
-
// setup leaving view
if (leavingView) {
// leaving content
let leavingContent = new Animation(leavingView.contentRef());
this.add(leavingContent);
- leavingContent
- .before.addClass(SHOW_VIEW_CSS)
- .before.setStyles({ zIndex: leavingView.index });
if (backDirection) {
+ // leaving content, back direction
leavingContent
.fromTo(TRANSLATEX, CENTER, '100%')
.fromTo(OPACITY, 1, 1);
} else {
+ // leaving content, forward direction
leavingContent
.fromTo(TRANSLATEX, CENTER, OFF_LEFT)
.fromTo(OPACITY, 1, OFF_OPACITY);
}
if (leavingHasNavbar) {
+ // leaving page has a navbar
let leavingNavBar = new Animation(leavingView.navbarRef());
let leavingBackButton = new Animation(leavingView.backBtnRef());
let leavingTitle = new Animation(leavingView.titleRef());
@@ -145,25 +144,28 @@ class IOSTransition extends Animation {
.add(leavingNavbarBg);
this.add(leavingNavBar);
- leavingBackButton
- .after.removeClass(SHOW_BACK_BTN_CSS)
- .fadeOut();
-
+ // fade out leaving navbar items
+ leavingBackButton.fadeOut();
leavingTitle.fadeOut();
leavingNavbarItems.fadeOut();
- // set properties depending on direction
if (backDirection) {
- // back direction
+ // leaving navbar, back direction
leavingTitle.fromTo(TRANSLATEX, CENTER, '100%');
+
if (enteringHasNavbar) {
- // this is an entering navbar, just fade this out
+ // leaving navbar, back direction, and there's an entering navbar
+ // should just fade out, no sliding
leavingNavbarBg
.fromTo(TRANSLATEX, CENTER, CENTER)
.fadeOut();
} else {
- leavingNavbarBg.fromTo(TRANSLATEX, CENTER, '100%');
+ // leaving navbar, back direction, and there's no entering navbar
+ // should just slide out, no fading out
+ leavingNavbarBg
+ .fromTo(TRANSLATEX, CENTER, '100%')
+ .fromTo(OPACITY, 1, 1);
}
let leavingBackBtnText = new Animation(leavingView.backBtnTextRef());
@@ -171,7 +173,7 @@ class IOSTransition extends Animation {
leavingNavBar.add(leavingBackBtnText);
} else {
- // forward direction
+ // leaving navbar, forward direction
leavingTitle.fromTo(TRANSLATEX, CENTER, OFF_LEFT);
}
}
diff --git a/ionic/transitions/md-transition.ts b/ionic/transitions/md-transition.ts
index 1bacee754e..2ead0ff4e3 100644
--- a/ionic/transitions/md-transition.ts
+++ b/ionic/transitions/md-transition.ts
@@ -4,16 +4,13 @@ import {Animation} from '../animations/animation';
const TRANSLATEY = 'translateY';
const OFF_BOTTOM = '40px';
const CENTER = '0px'
-const SHOW_NAVBAR_CSS = 'show-navbar';
-const SHOW_VIEW_CSS = 'show-view';
const SHOW_BACK_BTN_CSS = 'show-back-button';
-const TABBAR_HEIGHT = '69px';
class MDTransition extends Animation {
constructor(navCtrl, opts) {
- opts.renderDelay = 160;
+ //opts.renderDelay = 80;
super(null, opts);
// what direction is the transition going
@@ -27,98 +24,34 @@ class MDTransition extends Animation {
let enteringHasNavbar = enteringView.hasNavbar();
let leavingHasNavbar = leavingView && leavingView.hasNavbar();
-
// entering content item moves in bottom to center
- let enteringContent = new Animation(enteringView.contentRef());
- enteringContent
- .before.addClass(SHOW_VIEW_CSS)
- .before.setStyles({ zIndex: enteringView.index });
- this.add(enteringContent);
+ let enteringPage = new Animation(enteringView.pageRef());
+ this.add(enteringPage);
if (backDirection) {
this.duration(200).easing('cubic-bezier(0.47,0,0.745,0.715)');
- enteringContent.fromTo(TRANSLATEY, CENTER, CENTER);
+ enteringPage.fromTo(TRANSLATEY, CENTER, CENTER);
} else {
this.duration(280).easing('cubic-bezier(0.36,0.66,0.04,1)');
- enteringContent
+ enteringPage
.fromTo(TRANSLATEY, OFF_BOTTOM, CENTER)
.fadeIn();
}
-
// entering navbar
- if (enteringHasNavbar) {
- let enteringNavBar = new Animation(enteringView.navbarRef());
- enteringNavBar
- .before.addClass(SHOW_NAVBAR_CSS)
- .before.setStyles({ zIndex: enteringView.index + 10 });
- this.add(enteringNavBar);
-
- if (backDirection) {
- enteringNavBar.fromTo(TRANSLATEY, CENTER, CENTER);
-
- } else {
- enteringNavBar
- .fromTo(TRANSLATEY, OFF_BOTTOM, CENTER)
- .fadeIn();
- }
-
- if (enteringView.enableBack()) {
- let enteringBackButton = new Animation(enteringView.backBtnRef());
- enteringBackButton.before.addClass(SHOW_BACK_BTN_CSS);
- enteringNavBar.add(enteringBackButton);
- }
+ if (enteringHasNavbar && enteringView.enableBack()) {
+ let enteringBackButton = new Animation(enteringView.backBtnRef());
+ enteringBackButton.before.addClass(SHOW_BACK_BTN_CSS);
+ this.add(enteringBackButton);
}
// setup leaving view
- if (leavingView) {
+ if (leavingView && backDirection) {
// leaving content
- let leavingContent = new Animation(leavingView.contentRef());
- this.add(leavingContent);
- leavingContent
- .before.addClass(SHOW_VIEW_CSS)
- .before.setStyles({ zIndex: leavingView.index });
-
-
- if (backDirection) {
- this.duration(200).easing('cubic-bezier(0.47,0,0.745,0.715)');
- leavingContent
- .fromTo(TRANSLATEY, CENTER, OFF_BOTTOM)
- .fadeOut();
- }
-
-
- if (leavingHasNavbar) {
- if (backDirection) {
- let leavingNavBar = new Animation(leavingView.navbarRef());
- this.add(leavingNavBar);
-
- leavingNavBar
- .before.setStyles({ zIndex: leavingView.index + 10 })
- .fadeOut();
- }
-
- }
- }
-
- let viewLength = navCtrl.length();
- if ((viewLength === 1 || viewLength === 2) && navCtrl.tabs) {
- let tabBarEle = navCtrl.tabs.elementRef.nativeElement.querySelector('ion-tab-bar-section');
- let tabBar = new Animation(tabBarEle);
-
- if (viewLength === 1 && backDirection) {
- tabBar
- .fromTo('height', '0px', TABBAR_HEIGHT)
- .fadeIn();
-
- } else if (viewLength === 2 && !backDirection) {
- tabBar
- .fromTo('height', TABBAR_HEIGHT, '0px')
- .fadeOut();
- }
-
- this.add(tabBar);
+ this.duration(200).easing('cubic-bezier(0.47,0,0.745,0.715)');
+ let leavingPage = new Animation(leavingView.pageRef());
+ this.add(leavingPage.fromTo(TRANSLATEY, CENTER, OFF_BOTTOM).fadeOut());
}
}
diff --git a/ionic/util/util.scss b/ionic/util/util.scss
index f9cebfa284..15a6b3d186 100755
--- a/ionic/util/util.scss
+++ b/ionic/util/util.scss
@@ -20,8 +20,49 @@
background: none !important;
}
-.hide.hide.hide {
- display: none;
+.hide,
+[hidden],
+template,
+root-anchor {
+ display: none !important;
+}
+
+
+// Content Padding
+// --------------------------------------------------
+
+$content-padding: 16px !default;
+
+
+[padding],
+[padding] > scroll-content {
+ padding: $content-padding;
+}
+
+[padding-top] {
+ padding-top: $content-padding;
+}
+
+[padding-right] {
+ padding-right: $content-padding;
+}
+
+[padding-bottom] {
+ padding-bottom: $content-padding;
+}
+
+[padding-left] {
+ padding-left: $content-padding;
+}
+
+[padding-vertical] {
+ padding-top: $content-padding;
+ padding-bottom: $content-padding;
+}
+
+[padding-horizontal] {
+ padding-right: $content-padding;
+ padding-left: $content-padding;
}
diff --git a/ionic/util/util.ts b/ionic/util/util.ts
index d0ee00d697..466bcbf532 100644
--- a/ionic/util/util.ts
+++ b/ionic/util/util.ts
@@ -167,12 +167,10 @@ export function getQuerystring(url, key) {
const startIndex = url.indexOf('?');
if (startIndex !== -1) {
const queries = url.slice(startIndex + 1).split('&');
- if (queries.length) {
- queries.forEach((param) => {
- var split = param.split('=');
- queryParams[split[0]] = split[1].split('#')[0];
- });
- }
+ queries.forEach((param) => {
+ var split = param.split('=');
+ queryParams[split[0].toLowerCase()] = split[1].split('#')[0];
+ });
}
if (key) {
return queryParams[key] || '';
diff --git a/package.json b/package.json
index b5342fbd21..4ca03dd74f 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,6 @@
"mkdirp": "^0.5.1",
"node-html-encoder": "0.0.2",
"node-libs-browser": "^0.5.2",
- "node-uuid": "^1.4.1",
"q": "^1.4.1",
"request": "2.53.0",
"run-sequence": "^1.1.0",
diff --git a/scripts/e2e/e2e.template.html b/scripts/e2e/e2e.template.html
index 27eba2a0c0..df8985f237 100644
--- a/scripts/e2e/e2e.template.html
+++ b/scripts/e2e/e2e.template.html
@@ -2,22 +2,10 @@
-
+