Fixed up some nav stuff

This commit is contained in:
Max Lynch
2013-11-17 14:26:41 -06:00
parent 845af19d73
commit 097f8ce98a
8 changed files with 637 additions and 363 deletions

110
dist/css/ionic.css vendored
View File

@ -3811,7 +3811,7 @@ button.item-button-right:after {
* Nav
* --------------------------------------------------
*/
.nav-content {
.nav-page {
position: absolute;
width: 100%;
height: 100%;
@ -4801,50 +4801,94 @@ a.button {
100% {
-webkit-transform: translate3d(100%, 0, 0); } }
.slide-in-left.ng-enter, .slide-in-left > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInLeft; }
.slide-in-left.ng-leave, .slide-in-left > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft; }
.slide-in-left {
-webkit-transform: translate3d(0%, 0, 0); }
.slide-in-left.ng-enter, .slide-in-left > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInLeft; }
.slide-in-left.ng-leave, .slide-in-left > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft; }
.slide-out-left.ng-enter, .slide-out-left > .ng-enter {
.slide-in-left-add {
-webkit-transform: translate3d(100%, 0, 0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft; }
.slide-out-left.ng-leave, .slide-out-left > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out; }
.slide-in-left-add-active {
-webkit-animation-name: slideInLeft; }
.slide-in-right.ng-enter, .slide-in-right > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight; }
.slide-in-right.ng-leave, .slide-in-right > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight; }
.slide-out-left {
-webkit-transform: translate3d(-100%, 0, 0); }
.slide-out-left.ng-enter, .slide-out-left > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft; }
.slide-out-left.ng-leave, .slide-out-left > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft; }
.slide-out-right.ng-enter, .slide-out-right > .ng-enter {
.slide-out-left-add {
-webkit-transform: translate3d(0, 0, 0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight; }
.slide-out-right.ng-leave, .slide-out-right > .ng-leave {
-webkit-animation-timing-function: ease-in-out; }
.slide-out-left-add-active {
-webkit-animation-name: slideOutLeft; }
.slide-in-right {
-webkit-transform: translate3d(0%, 0, 0); }
.slide-in-right.ng-enter, .slide-in-right > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight; }
.slide-in-right.ng-leave, .slide-in-right > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight; }
.slide-in-right-add {
-webkit-transform: translate3d(-100%, 0, 0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out; }
.slide-in-right-add-active {
-webkit-animation-name: slideInRight; }
.slide-out-right {
-webkit-transform: translate3d(100%, 0, 0); }
.slide-out-right.ng-enter, .slide-out-right > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight; }
.slide-out-right.ng-leave, .slide-out-right > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight; }
.slide-out-right-add {
-webkit-transform: translate3d(0, 0, 0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out; }
.slide-out-right-add-active {
-webkit-animation-name: slideOutRight; }
@-webkit-keyframes slideInUp {
0% {
-webkit-transform: translate3d(0, 100%, 0);

View File

@ -23597,7 +23597,7 @@ angular.module('ionic.ui.content', [])
.directive('pane', function() {
return {
restrict: 'E',
compile: function(element, attr) {
link: function(scope, element, attr) {
element.addClass('pane');
}
}
@ -23877,28 +23877,78 @@ angular.module('ionic.ui.loading', [])
(function() {
'use strict';
/**
* @description
* The NavController is a navigation stack View Controller modelled off of
* UINavigationController from Cocoa Touch. With the Nav Controller, you can
* "push" new "pages" on to the navigation stack, and then pop them off to go
* back. The NavController controls a navigation bar with a back button and title
* which updates as the pages switch.
*
* The NavController makes sure to not recycle scopes of old pages
* so that a pop will still show the same state that the user left.
*
* However, once a page is popped, its scope is destroyed and will have to be
* recreated then next time it is pushed.
*
*/
angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.gesture', 'ionic.service.platform', 'ngAnimate'])
.controller('NavCtrl', ['$scope', '$element', '$animate', '$compile', 'TemplateLoader', 'Platform', function($scope, $element, $animate, $compile, TemplateLoader, Platform) {
.controller('NavCtrl', ['$scope', '$element', '$animate', '$compile', '$timeout', 'TemplateLoader', 'Platform', function($scope, $element, $animate, $compile, $timeout, TemplateLoader, Platform) {
var _this = this;
angular.extend(this, ionic.controllers.NavController.prototype);
var pushInAnimation = $scope.pushInAnimation || 'slide-in-left';
var pushOutAnimation = $scope.pushOutAnimation || 'slide-out-left';
var popInAnimation = $scope.popInAnimation || 'slide-in-right';
var popOutAnimation = $scope.popOutAnimation || 'slide-out-right';
// Remove some push classnames
var cleanElementAnimations = function(el) {
el.removeClass(pushInAnimation);
el.removeClass(pushOutAnimation);
el.removeClass(popInAnimation);
el.removeClass(popOutAnimation);
}
/**
* Push a template onto the navigation stack.
* @param {string} templateUrl the URL of the template to load.
*/
this.pushFromTemplate = ionic.throttle(function(templateUrl) {
var childScope = $scope.$new();
childScope.isVisible = true;
var last = _this.getTopController();
// Load the given template
TemplateLoader.load(templateUrl).then(function(templateString) {
// Compile the template with the new scrope, and append it to the navigation's content area
// Compile the template with the new scope, and append
// it to the navigation's content area
var el = $compile(templateString)(childScope, function(cloned, scope) {
var content = angular.element($element[0].querySelector('.content, .scroll'));
$animate.enter(cloned, angular.element(content));
// If there was a last controller, remove it and mark the new
// one to animate
if(last) {
// Push animate
cleanElementAnimations(last.element);
$animate.addClass(last.element, pushOutAnimation, function() {
last.element[0].style.display = 'none';
last.element.removeClass(pushOutAnimation);
});
}
if(last) {
// We will need to animate in the new page since we have an old page
cloned.addClass(pushInAnimation);
$animate.addClass(cloned, pushInAnimation);
}
$animate.enter(cloned, $element, null, function() {
});
});
});
}, 300, {
@ -23907,13 +23957,34 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
// Pop function, throttled
this.popController = ionic.throttle(function() {
_this.pop();
$scope.$broadcast('navs.pop');
var last = _this.pop();
var next = _this.getTopController();
if(last) {
cleanElementAnimations(last.element);
$animate.addClass(last.element, popOutAnimation, function() {
last.scope.$destroy();
last.element.remove();
});
}
// Animate the next one in
if(next) {
cleanElementAnimations(next.element);
$animate.addClass(next.element, popInAnimation)
next.element[0].style.display = 'block';
}
$scope.$parent.$broadcast('navigation.pop');
}, 300, {
trailing: false
});
// Extend the low-level navigation controller
// for this angular controller
ionic.controllers.NavController.call(this, {
content: {
},
@ -23955,8 +24026,19 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
* nav-content directive when it is linked to a scope on the page.
*/
$scope.pushController = function(scope, element) {
_this.push(scope);
$scope.$broadcast('navs.push', scope);
_this.push({
scope: scope,
element: element
});
$scope.$parent.$broadcast('navigation.push', scope);
};
this.pushController = function(scope, element) {
_this.push({
scope: scope,
element: element
});
$scope.$parent.$broadcast('navigation.push', scope);
};
$scope.navController = this;
@ -23967,7 +24049,10 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
});
}])
.directive('navs', function() {
/**
* The main directive for the controller.
*/
.directive('navigation', function() {
return {
restrict: 'E',
replace: true,
@ -23975,26 +24060,54 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
controller: 'NavCtrl',
//templateUrl: 'ext/angular/tmpl/ionicTabBar.tmpl.html',
template: '<div class="view" ng-transclude></div>',
scope: {
first: '@',
pushAnimation: '@',
popAnimation: '@'
},
link: function($scope, $element, $attr, navCtrl) {
$scope.pushAnimation = $scope.pushAnimation || 'slide-in-left';
$scope.popAnimation = $scope.popAnimation || 'slide-out-left';
if($scope.first) {
navCtrl.pushFromTemplate($scope.first);
}
}
};
})
/**
* Our Nav Bar directive which updates as the controller state changes.
*/
.directive('navBar', function() {
return {
restrict: 'E',
require: '^navs',
require: '^navigation',
replace: true,
scope: {
type: '@',
backButtonType: '@',
backButtonLabel: '@',
backButtonIcon: '@',
alignTitle: '@'
},
template: '<header class="bar bar-header nav-bar" ng-class="{hidden: !navController.navBar.isVisible}">' +
'<button ng-click="goBack()" class="button" ng-if="navController.controllers.length > 1" ng-class="backButtonType">Back</button>' +
'<h1 class="title">{{navController.getTopController().title}}</h1>' +
'<button ng-click="goBack()" class="button" ng-if="navController.controllers.length > 1" ng-class="backButtonType" ng-bind-html="backButtonContent"></button>' +
'<h1 class="title">{{navController.getTopController().scope.title}}</h1>' +
'</header>',
link: function($scope, $element, $attr, navCtrl) {
var backButton;
$scope.backButtonContent = '';
if($scope.backButtonIcon) {
$scope.backButtonContent += '<i class="icon ' + $scope.backButtonIcon + '"></i>';
}
if($scope.backButtonLabel) {
$scope.backButtonContent += ' ' + $scope.backButtonLabel
}
$scope.navController = navCtrl;
$scope.goBack = function() {
@ -24011,12 +24124,12 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
$scope.headerBarView = hb;
$scope.$parent.$on('navs.push', function() {
$scope.$parent.$on('navigation.push', function() {
backButton = angular.element($element[0].querySelector('.button'));
backButton.addClass($scope.backButtonType);
hb.align();
});
$scope.$parent.$on('navs.pop', function() {
$scope.$parent.$on('navigation.pop', function() {
hb.align();
});
@ -24027,141 +24140,79 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
};
})
.directive('navContent', ['Gesture', '$animate', '$compile', function(Gesture, $animate, $compile) {
// We need to animate the new controller into view.
var animatePushedController = function(childScope, clone, $element, isForward) {
var parent = angular.element($element.parent().parent().parent());
var title = angular.element(parent[0].querySelector('.title'));
// Clone the old title and insert it so we can animate it back into place for the new controller
var newTitle = angular.element(title.clone());
$compile(newTitle)(childScope);
title.after(newTitle);
// Grab the button so we can slide it in
var button = angular.element(parent[0].querySelector('.button'));
if(isForward) {
// Slide the button in
$animate.addClass(button, childScope.slideButtonInAnimation, function() {
$animate.removeClass(button, childScope.slideButtonInAnimation, function() {});
})
// Slide the new title in
$animate.addClass(newTitle, childScope.slideTitleInAnimation, function() {
$animate.removeClass(newTitle, childScope.slideTitleInAnimation, function() {
newTitle.scope().$destroy();
newTitle.remove();
});
});
// Grab the old title and slide it out
var title = $element.parent().parent().parent()[0].querySelector('.title');
$animate.addClass(angular.element(title), childScope.slideTitleOutAnimation, function() {
$animate.removeClass(angular.element(title), childScope.slideTitleOutAnimation, function() {
});
});
} else {
clone.addClass(childScope.slideBackInAnimation);
}
};
.directive('navPage', ['Gesture', '$animate', '$compile', function(Gesture, $animate, $compile) {
return {
restrict: 'ECA',
require: '^navs',
transclude: 'element',
compile: function(element, attr, transclude) {
return function($scope, $element, $attr, navCtrl) {
var lastParent, lastIndex, childScope, childElement;
restrict: 'AC',
require: '^navigation',
link: function($scope, $element, $attr, navCtrl) {
var lastParent, lastIndex, childScope, childElement;
// Store that we should go forwards on the animation. This toggles
// based on the visibility sequence (to support reverse transitions)
var lastDirection = null;
// Store that we should go forwards on the animation. This toggles
// based on the visibility sequence (to support reverse transitions)
var lastDirection = null;
$scope.title = $attr.title;
$scope.pushAnimation = $attr.pushAnimation || 'slide-in-left';
$scope.popAnimation = $attr.popAnimation || 'slide-in-right';
$scope.slideTitleInAnimation = $attr.slideTitleInAnimation || 'bar-title-in';
$scope.slideTitleOutAnimation = $attr.slideTitleOutAnimation || 'bar-title-out';
$scope.slideButtonInAnimation = $attr.slideButtonInAnimation || 'bar-button-in';
$scope.slideButtonOutAnimation = $attr.slideButtonOutAnimation || 'bar-button-out';
$scope.title = $attr.title;
if($attr.navBar === "false") {
navCtrl.hideNavBar();
} else {
navCtrl.showNavBar();
}
$scope.visibilityChanged = function(direction) {
lastDirection = direction;
if($scope.isVisible) {
$scope.$broadcast('navContent.shown');
} else {
$scope.$broadcast('navContent.hidden');
}
if(!childElement) {
return;
}
var clone = childElement;
if(direction == 'push') {
clone.addClass(childScope.pushAnimation);
clone.removeClass(childScope.popAnimation);
} else if(direction == 'pop') {
clone.addClass(childScope.popAnimation);
clone.removeClass(childScope.pushAnimation);
}
};
// Push this controller onto the stack
$scope.pushController($scope, $element);
$scope.$watch('isVisible', function(value) {
if(value) {
childScope = $scope.$new();
transclude(childScope, function(clone) {
childElement = clone;
if(lastDirection == 'push') {
clone.addClass(childScope.pushAnimation);
} else if(lastDirection == 'pop') {
clone.addClass(childScope.popAnimation);
}
$animate.enter(clone, $element.parent(), $element, function() {
clone.removeClass(childScope.pushAnimation);
clone.removeClass(childScope.popAnimation);
});
});
} else {
// Taken from ngIf
if(childElement) {
// Check if this is visible, and if so, create it and show it
$animate.leave(childElement, function() {
if(childScope) {
childElement.removeClass(childScope.pushAnimation);
childElement.removeClass(childScope.popAnimation);
}
});
childElement = undefined;
}
if(childScope) {
childScope.$destroy();
childScope = undefined;
}
}
});
if($attr.navBar === "false") {
navCtrl.hideNavBar();
} else {
navCtrl.showNavBar();
}
$scope.$on('$destroy', function() {
if(childElement) {
childElement.remove();
}
});
// Push this controller onto the stack
navCtrl.pushController($scope, $element);
}
};
}]);
}
}])
.directive('navPush', function() {
return {
restrict: 'A',
link: function($scope, $element, $attr) {
var templateUrl = $attr.navPush;
var pushTemplate = function(e) {
$scope.$apply(function() {
$scope.navController && $scope.navController.pushFromTemplate(templateUrl);
});
return false;
};
$element.bind('tap', pushTemplate);
$scope.$on('$destroy', function() {
$element.unbind('tap', pushTemplate);
});
}
}
})
.directive('navPop', function() {
return {
restrict: 'A',
link: function($scope, $element, $attr, navCtrl) {
var popTemplate = function(e) {
$scope.$apply(function() {
$scope.navController && navController.pop();
});
return false;
};
$element.bind('tap', popTemplate);
$scope.$on('$destroy', function() {
$element.unbind('tap', popTemplate);
});
}
}
})
})();
;

View File

@ -10,7 +10,7 @@ angular.module('ionic.ui.content', [])
.directive('pane', function() {
return {
restrict: 'E',
compile: function(element, attr) {
link: function(scope, element, attr) {
element.addClass('pane');
}
}

View File

@ -1,28 +1,78 @@
(function() {
'use strict';
/**
* @description
* The NavController is a navigation stack View Controller modelled off of
* UINavigationController from Cocoa Touch. With the Nav Controller, you can
* "push" new "pages" on to the navigation stack, and then pop them off to go
* back. The NavController controls a navigation bar with a back button and title
* which updates as the pages switch.
*
* The NavController makes sure to not recycle scopes of old pages
* so that a pop will still show the same state that the user left.
*
* However, once a page is popped, its scope is destroyed and will have to be
* recreated then next time it is pushed.
*
*/
angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.gesture', 'ionic.service.platform', 'ngAnimate'])
.controller('NavCtrl', ['$scope', '$element', '$animate', '$compile', 'TemplateLoader', 'Platform', function($scope, $element, $animate, $compile, TemplateLoader, Platform) {
.controller('NavCtrl', ['$scope', '$element', '$animate', '$compile', '$timeout', 'TemplateLoader', 'Platform', function($scope, $element, $animate, $compile, $timeout, TemplateLoader, Platform) {
var _this = this;
angular.extend(this, ionic.controllers.NavController.prototype);
var pushInAnimation = $scope.pushInAnimation || 'slide-in-left';
var pushOutAnimation = $scope.pushOutAnimation || 'slide-out-left';
var popInAnimation = $scope.popInAnimation || 'slide-in-right';
var popOutAnimation = $scope.popOutAnimation || 'slide-out-right';
// Remove some push classnames
var cleanElementAnimations = function(el) {
el.removeClass(pushInAnimation);
el.removeClass(pushOutAnimation);
el.removeClass(popInAnimation);
el.removeClass(popOutAnimation);
}
/**
* Push a template onto the navigation stack.
* @param {string} templateUrl the URL of the template to load.
*/
this.pushFromTemplate = ionic.throttle(function(templateUrl) {
var childScope = $scope.$new();
childScope.isVisible = true;
var last = _this.getTopController();
// Load the given template
TemplateLoader.load(templateUrl).then(function(templateString) {
// Compile the template with the new scrope, and append it to the navigation's content area
// Compile the template with the new scope, and append
// it to the navigation's content area
var el = $compile(templateString)(childScope, function(cloned, scope) {
var content = angular.element($element[0].querySelector('.content, .scroll'));
$animate.enter(cloned, angular.element(content));
// If there was a last controller, remove it and mark the new
// one to animate
if(last) {
// Push animate
cleanElementAnimations(last.element);
$animate.addClass(last.element, pushOutAnimation, function() {
last.element[0].style.display = 'none';
last.element.removeClass(pushOutAnimation);
});
}
if(last) {
// We will need to animate in the new page since we have an old page
cloned.addClass(pushInAnimation);
$animate.addClass(cloned, pushInAnimation);
}
$animate.enter(cloned, $element, null, function() {
});
});
});
}, 300, {
@ -31,13 +81,34 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
// Pop function, throttled
this.popController = ionic.throttle(function() {
_this.pop();
$scope.$broadcast('navs.pop');
var last = _this.pop();
var next = _this.getTopController();
if(last) {
cleanElementAnimations(last.element);
$animate.addClass(last.element, popOutAnimation, function() {
last.scope.$destroy();
last.element.remove();
});
}
// Animate the next one in
if(next) {
cleanElementAnimations(next.element);
$animate.addClass(next.element, popInAnimation)
next.element[0].style.display = 'block';
}
$scope.$parent.$broadcast('navigation.pop');
}, 300, {
trailing: false
});
// Extend the low-level navigation controller
// for this angular controller
ionic.controllers.NavController.call(this, {
content: {
},
@ -79,8 +150,19 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
* nav-content directive when it is linked to a scope on the page.
*/
$scope.pushController = function(scope, element) {
_this.push(scope);
$scope.$broadcast('navs.push', scope);
_this.push({
scope: scope,
element: element
});
$scope.$parent.$broadcast('navigation.push', scope);
};
this.pushController = function(scope, element) {
_this.push({
scope: scope,
element: element
});
$scope.$parent.$broadcast('navigation.push', scope);
};
$scope.navController = this;
@ -91,7 +173,10 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
});
}])
.directive('navs', function() {
/**
* The main directive for the controller.
*/
.directive('navigation', function() {
return {
restrict: 'E',
replace: true,
@ -99,26 +184,54 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
controller: 'NavCtrl',
//templateUrl: 'ext/angular/tmpl/ionicTabBar.tmpl.html',
template: '<div class="view" ng-transclude></div>',
scope: {
first: '@',
pushAnimation: '@',
popAnimation: '@'
},
link: function($scope, $element, $attr, navCtrl) {
$scope.pushAnimation = $scope.pushAnimation || 'slide-in-left';
$scope.popAnimation = $scope.popAnimation || 'slide-out-left';
if($scope.first) {
navCtrl.pushFromTemplate($scope.first);
}
}
};
})
/**
* Our Nav Bar directive which updates as the controller state changes.
*/
.directive('navBar', function() {
return {
restrict: 'E',
require: '^navs',
require: '^navigation',
replace: true,
scope: {
type: '@',
backButtonType: '@',
backButtonLabel: '@',
backButtonIcon: '@',
alignTitle: '@'
},
template: '<header class="bar bar-header nav-bar" ng-class="{hidden: !navController.navBar.isVisible}">' +
'<button ng-click="goBack()" class="button" ng-if="navController.controllers.length > 1" ng-class="backButtonType">Back</button>' +
'<h1 class="title">{{navController.getTopController().title}}</h1>' +
'<button ng-click="goBack()" class="button" ng-if="navController.controllers.length > 1" ng-class="backButtonType" ng-bind-html="backButtonContent"></button>' +
'<h1 class="title">{{navController.getTopController().scope.title}}</h1>' +
'</header>',
link: function($scope, $element, $attr, navCtrl) {
var backButton;
$scope.backButtonContent = '';
if($scope.backButtonIcon) {
$scope.backButtonContent += '<i class="icon ' + $scope.backButtonIcon + '"></i>';
}
if($scope.backButtonLabel) {
$scope.backButtonContent += ' ' + $scope.backButtonLabel
}
$scope.navController = navCtrl;
$scope.goBack = function() {
@ -135,12 +248,12 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
$scope.headerBarView = hb;
$scope.$parent.$on('navs.push', function() {
$scope.$parent.$on('navigation.push', function() {
backButton = angular.element($element[0].querySelector('.button'));
backButton.addClass($scope.backButtonType);
hb.align();
});
$scope.$parent.$on('navs.pop', function() {
$scope.$parent.$on('navigation.pop', function() {
hb.align();
});
@ -151,140 +264,78 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges
};
})
.directive('navContent', ['Gesture', '$animate', '$compile', function(Gesture, $animate, $compile) {
// We need to animate the new controller into view.
var animatePushedController = function(childScope, clone, $element, isForward) {
var parent = angular.element($element.parent().parent().parent());
var title = angular.element(parent[0].querySelector('.title'));
// Clone the old title and insert it so we can animate it back into place for the new controller
var newTitle = angular.element(title.clone());
$compile(newTitle)(childScope);
title.after(newTitle);
// Grab the button so we can slide it in
var button = angular.element(parent[0].querySelector('.button'));
if(isForward) {
// Slide the button in
$animate.addClass(button, childScope.slideButtonInAnimation, function() {
$animate.removeClass(button, childScope.slideButtonInAnimation, function() {});
})
// Slide the new title in
$animate.addClass(newTitle, childScope.slideTitleInAnimation, function() {
$animate.removeClass(newTitle, childScope.slideTitleInAnimation, function() {
newTitle.scope().$destroy();
newTitle.remove();
});
});
// Grab the old title and slide it out
var title = $element.parent().parent().parent()[0].querySelector('.title');
$animate.addClass(angular.element(title), childScope.slideTitleOutAnimation, function() {
$animate.removeClass(angular.element(title), childScope.slideTitleOutAnimation, function() {
});
});
} else {
clone.addClass(childScope.slideBackInAnimation);
}
};
.directive('navPage', ['Gesture', '$animate', '$compile', function(Gesture, $animate, $compile) {
return {
restrict: 'ECA',
require: '^navs',
transclude: 'element',
compile: function(element, attr, transclude) {
return function($scope, $element, $attr, navCtrl) {
var lastParent, lastIndex, childScope, childElement;
restrict: 'AC',
require: '^navigation',
link: function($scope, $element, $attr, navCtrl) {
var lastParent, lastIndex, childScope, childElement;
// Store that we should go forwards on the animation. This toggles
// based on the visibility sequence (to support reverse transitions)
var lastDirection = null;
// Store that we should go forwards on the animation. This toggles
// based on the visibility sequence (to support reverse transitions)
var lastDirection = null;
$scope.title = $attr.title;
$scope.pushAnimation = $attr.pushAnimation || 'slide-in-left';
$scope.popAnimation = $attr.popAnimation || 'slide-in-right';
$scope.slideTitleInAnimation = $attr.slideTitleInAnimation || 'bar-title-in';
$scope.slideTitleOutAnimation = $attr.slideTitleOutAnimation || 'bar-title-out';
$scope.slideButtonInAnimation = $attr.slideButtonInAnimation || 'bar-button-in';
$scope.slideButtonOutAnimation = $attr.slideButtonOutAnimation || 'bar-button-out';
$scope.title = $attr.title;
if($attr.navBar === "false") {
navCtrl.hideNavBar();
} else {
navCtrl.showNavBar();
}
$scope.visibilityChanged = function(direction) {
lastDirection = direction;
if($scope.isVisible) {
$scope.$broadcast('navContent.shown');
} else {
$scope.$broadcast('navContent.hidden');
}
if(!childElement) {
return;
}
var clone = childElement;
if(direction == 'push') {
clone.addClass(childScope.pushAnimation);
clone.removeClass(childScope.popAnimation);
} else if(direction == 'pop') {
clone.addClass(childScope.popAnimation);
clone.removeClass(childScope.pushAnimation);
}
};
// Push this controller onto the stack
$scope.pushController($scope, $element);
$scope.$watch('isVisible', function(value) {
if(value) {
childScope = $scope.$new();
transclude(childScope, function(clone) {
childElement = clone;
if(lastDirection == 'push') {
clone.addClass(childScope.pushAnimation);
} else if(lastDirection == 'pop') {
clone.addClass(childScope.popAnimation);
}
$animate.enter(clone, $element.parent(), $element, function() {
clone.removeClass(childScope.pushAnimation);
clone.removeClass(childScope.popAnimation);
});
});
} else {
// Taken from ngIf
if(childElement) {
// Check if this is visible, and if so, create it and show it
$animate.leave(childElement, function() {
if(childScope) {
childElement.removeClass(childScope.pushAnimation);
childElement.removeClass(childScope.popAnimation);
}
});
childElement = undefined;
}
if(childScope) {
childScope.$destroy();
childScope = undefined;
}
}
});
if($attr.navBar === "false") {
navCtrl.hideNavBar();
} else {
navCtrl.showNavBar();
}
$scope.$on('$destroy', function() {
if(childElement) {
childElement.remove();
}
});
// Push this controller onto the stack
navCtrl.pushController($scope, $element);
}
};
}]);
}
}])
.directive('navPush', function() {
return {
restrict: 'A',
link: function($scope, $element, $attr) {
var templateUrl = $attr.navPush;
var pushTemplate = function(e) {
$scope.$apply(function() {
$scope.navController && $scope.navController.pushFromTemplate(templateUrl);
});
return false;
};
$element.bind('tap', pushTemplate);
$scope.$on('$destroy', function() {
$element.unbind('tap', pushTemplate);
});
}
}
})
.directive('navPop', function() {
return {
restrict: 'A',
link: function($scope, $element, $attr, navCtrl) {
var popTemplate = function(e) {
$scope.$apply(function() {
$scope.navController && navController.pop();
});
return false;
};
$element.bind('tap', popTemplate);
$scope.$on('$destroy', function() {
$element.unbind('tap', popTemplate);
});
}
}
})
})();

View File

@ -12,7 +12,6 @@
position: fixed;
width: 100%;
height: 100%;
background-color: black;
}
.slide-in-slide-out {
/*
@ -28,22 +27,21 @@
</head>
<body>
<navs>
<nav-bar type="bar-primary" back-button-type="button-pure" align-title="left">
<navigation first="page.html">
<nav-bar type="bar-primary" back-button-type="button-pure button-icon" back-button-icon="ion-arrow-left-c">
</nav-bar>
<div ng-controller="AppCtrl">
<content has-header="true">
</content>
</div>
</navs>
</navigation>
<script id="page.html" type="text/ng-template">
<div title="Home home home home home home home home home" ng-controller="CatsCtrl" class="nav-content">
<h1></h1>
<a href="#" class="button button-royal" ng-click="goNext()">Next</a>
<button class="button button-assertive" ng-click="thisThing()">Doit</button>
<list><list-item ng-repeat="item in items" on-select="goNext()">Test</list-item></list>
<div title="title" class="nav-page">
<div ng-controller="CatsCtrl">
<content has-header="true">
<h1></h1>
<a href="#" class="button button-royal" nav-push="page.html">Next</a>
<button class="button button-assertive" ng-click="thisThing()">Doit</button>
<list><list-item ng-repeat="item in items" on-select="goNext()">Test</list-item></list>
</content>
</div>
</div>
</script>
@ -68,9 +66,6 @@
angular.module('navTest', ['ionic', 'ngAnimate'])
.controller('AppCtrl', function($scope, $compile, $element) {
$scope.navController.pushFromTemplate('page.html');
})
.controller('CatsCtrl', function($scope, $compile, $element) {
$scope.$on('navContent.shown', function() {

View File

@ -0,0 +1,83 @@
<html ng-app="navTest">
<head>
<meta charset="utf-8">
<title>Nav Bars</title>
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="/vendor/font-awesome/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
<style>
.view {
position: fixed;
width: 100%;
height: 100%;
background-color: black;
}
.slide-in-slide-out {
/*
-webkit-transform: translate3d(0%, 0, 0);
transform: translate3d(0%, 0, 0);
-webkit-transition: -webkit-transform 1s ease-in-out;
transition: transform 1s ease-in-out;
*/
}
</style>
<script src="../../../../dist/js/ionic.js"></script>
<script src="../../../../dist/js/ionic-angular.js"></script>
</head>
<body>
<navigation first="page.html">
<nav-bar type="bar-primary" back-button-type="button-pure" align-title="left">
</nav-bar>
</navigation>
<script id="page.html" type="text/ng-template">
<div title="title" class="nav-page">
<div ng-controller="CatsCtrl">
<content has-header="true">
{{secretNumber}}
<list><item ng-repeat="item in items" nav-push="page.html">{{item.t}}</item></list>
<button nav-push="page.html" class="button button-assertive">Do it</button>
</content>
</div>
</div>
</script>
<script>
angular.module('navTest', ['ionic', 'ngAnimate'])
.controller('CatsCtrl', function($scope, $compile, $element) {
$scope.$on('navContent.shown', function() {
console.log('SHOWN');
});
$scope.$on('navContent.hidden', function() {
console.log('HIDDEN');
});
$scope.secretNumber = Math.floor(Math.random() * 100);
$scope.doit = function() { alert('waht'); };
var items = [
{t: 'This one'},
{t: 'Hmm, maybe this one'},
{t: 'Not that one, this one'},
{t: 'Um, this one?'},
{t: 'No, this one'}
];
items = items.sort(function() {
return .5 - Math.random();
});
$scope.items = items;
$scope.goNext = function() {
$scope.navController.pushFromTemplate('page.html');
};
});
</script>
</body>
</html>

View File

@ -41,6 +41,7 @@
}
.slide-in-left {
-webkit-transform: translate3d(0%,0,0);
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
@ -55,28 +56,80 @@
}
}
.slide-in-left-add {
-webkit-transform: translate3d(100%,0,0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
}
.slide-in-left-add-active {
-webkit-animation-name: slideInLeft;
}
.slide-out-left {
-webkit-transform: translate3d(-100%,0,0);
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft;
}
&.ng-leave, > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft;
}
}
.slide-out-left {
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutLeft;
}
&.ng-leave, > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInLeft;
}
}
.slide-out-left-add {
-webkit-transform: translate3d(0,0,0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
}
.slide-out-left-add-active {
-webkit-animation-name: slideOutLeft;
}
.slide-in-right {
-webkit-transform: translate3d(0%,0,0);
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight;
}
&.ng-leave, > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight;
}
}
.slide-in-right-add {
-webkit-transform: translate3d(-100%,0,0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
}
.slide-in-right-add-active {
-webkit-animation-name: slideInRight;
}
.slide-out-right {
-webkit-transform: translate3d(100%,0,0);
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight;
}
&.ng-leave, > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
@ -86,18 +139,15 @@
}
.slide-out-right {
&.ng-enter, > .ng-enter {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideOutRight;
}
&.ng-leave, > .ng-leave {
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-name: slideInRight;
}
}
.slide-out-right-add {
-webkit-transform: translate3d(0,0,0);
-webkit-animation-duration: 250ms;
-webkit-animation-fill-mode: both;
-webkit-animation-timing-function: ease-in-out;
}
.slide-out-right-add-active {
-webkit-animation-name: slideOutRight;
}
$slide-in-up-function: cubic-bezier(.1, .7, .1, 1);

View File

@ -4,7 +4,7 @@
* --------------------------------------------------
*/
.nav-content {
.nav-page {
position: absolute;
width: 100%;
height: 100%;