From 2ea66ecfb3cf9afcbd0466851350b6110df3ce2a Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Mon, 18 Nov 2013 18:05:21 -0600 Subject: [PATCH] Initial working version of router based nav controller --- dist/js/ionic-angular.js | 131 ++++++++++++++++++ .../angular/src/directive/ionicNavRouter.js | 128 +++++++++++++++++ js/ext/angular/src/ionicAngular.js | 2 + js/ext/angular/test/navRouter.html | 119 ++++++++++++++++ 4 files changed, 380 insertions(+) create mode 100644 js/ext/angular/src/directive/ionicNavRouter.js create mode 100644 js/ext/angular/test/navRouter.html diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index d5036b6d33..482591b3cf 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -23942,6 +23942,7 @@ angular.module('ionic.ui', [ 'ionic.ui.content', 'ionic.ui.tabs', 'ionic.ui.nav', + 'ionic.ui.navRouter', 'ionic.ui.header', 'ionic.ui.sideMenu', 'ionic.ui.slideBox', @@ -23957,6 +23958,7 @@ angular.module('ionic', [ // Angular deps 'ngAnimate', + 'ngRoute', 'ngTouch', 'ngSanitize' ]); @@ -25254,6 +25256,135 @@ angular.module('ionic.ui.nav', ['ionic.service.templateLoad', 'ionic.service.ges } }) +})(); +; +(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. + * + */ + +var actualLocation = null; + +angular.module('ionic.ui.navRouter', []) + +.run(['$rootScope', function($rootScope) { + $rootScope.stackCursorPosition = 0; +}]) + +.directive('navRouter', ['$rootScope', '$location', '$window', '$route', function($rootScope, $location, $window, $route) { + return { + restrict: 'AC', + link: function($scope, $element, $attr) { + $scope.animation = $attr.animation; + + $element.addClass($scope.animation); + + $scope.isReverse = false; + + + var reverseTransition = ionic.throttle(function() { + console.log('REVERSE'); + $element.removeClass($scope.animation); + $element.addClass($scope.animation + '-reverse'); + }, 1000, { + }) + + var forwardTransition = ionic.throttle(function() { + console.log('FORWARD'); + $element.removeClass($scope.animation + '-reverse'); + $element.addClass($scope.animation); + }, 1000, { + }); + + $scope.$on('$routeChangeSuccess', function(e, a) { + console.log('ROUTE CHANGED', a, e); + }); + $scope.$on('$routeChangeStart', function(e, a) { + console.log('ROUTE START', a, e); + var back, historyState = $window.history.state; + + back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition); + if(back) { + reverseTransition(); + } else { + forwardTransition(); + } + }); + + $scope.$on('$locationChangeSuccess', function() { + // Store the new location + console.log('LOCATION CHANGE SUCCESS'); + $rootScope.actualLocation = $location.path(); + }); + + + // Keep track of location changes and update a stack pointer that tracks whether we are + // going forwards or back + $scope.$watch(function () { return $location.path() }, function (newLocation, oldLocation) { + if($rootScope.actualLocation === newLocation) { + + var back, historyState = $window.history.state; + + back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition); + + if (back) { + //back button + $rootScope.stackCursorPosition--; + } else { + //forward button + $rootScope.stackCursorPosition++; + } + + } else { + var currentRouteBeforeChange = $route.current; + + if (currentRouteBeforeChange) { + + $window.history.replaceState({ + position: $rootScope.stackCursorPosition + }); + + $rootScope.stackCursorPosition++; + } + } + }); + } + } +}]) + +.directive('navBack', ['$window', function($window) { + return { + restrict: 'AC', + require: '^?navRouter', + link: function($scope, $element, $attr, navCtrl) { + var goBack = function() { + $window.history.back(); + }; + $element.bind('tap', goBack); + $element.bind('click', goBack); + + $scope.$on('$destroy', function() { + $element.unbind('tap', goBack); + $element.unbind('click', goBack); + }); + } + } +}]); + })(); ; (function(ionic) { diff --git a/js/ext/angular/src/directive/ionicNavRouter.js b/js/ext/angular/src/directive/ionicNavRouter.js new file mode 100644 index 0000000000..6dccc86b41 --- /dev/null +++ b/js/ext/angular/src/directive/ionicNavRouter.js @@ -0,0 +1,128 @@ +(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. + * + */ + +var actualLocation = null; + +angular.module('ionic.ui.navRouter', []) + +.run(['$rootScope', function($rootScope) { + $rootScope.stackCursorPosition = 0; +}]) + +.directive('navRouter', ['$rootScope', '$location', '$window', '$route', function($rootScope, $location, $window, $route) { + return { + restrict: 'AC', + link: function($scope, $element, $attr) { + $scope.animation = $attr.animation; + + $element.addClass($scope.animation); + + $scope.isReverse = false; + + + var reverseTransition = ionic.throttle(function() { + console.log('REVERSE'); + $element.removeClass($scope.animation); + $element.addClass($scope.animation + '-reverse'); + }, 1000, { + }) + + var forwardTransition = ionic.throttle(function() { + console.log('FORWARD'); + $element.removeClass($scope.animation + '-reverse'); + $element.addClass($scope.animation); + }, 1000, { + }); + + $scope.$on('$routeChangeSuccess', function(e, a) { + console.log('ROUTE CHANGED', a, e); + }); + $scope.$on('$routeChangeStart', function(e, a) { + console.log('ROUTE START', a, e); + var back, historyState = $window.history.state; + + back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition); + if(back) { + reverseTransition(); + } else { + forwardTransition(); + } + }); + + $scope.$on('$locationChangeSuccess', function() { + // Store the new location + console.log('LOCATION CHANGE SUCCESS'); + $rootScope.actualLocation = $location.path(); + }); + + + // Keep track of location changes and update a stack pointer that tracks whether we are + // going forwards or back + $scope.$watch(function () { return $location.path() }, function (newLocation, oldLocation) { + if($rootScope.actualLocation === newLocation) { + + var back, historyState = $window.history.state; + + back = !!(historyState && historyState.position <= $rootScope.stackCursorPosition); + + if (back) { + //back button + $rootScope.stackCursorPosition--; + } else { + //forward button + $rootScope.stackCursorPosition++; + } + + } else { + var currentRouteBeforeChange = $route.current; + + if (currentRouteBeforeChange) { + + $window.history.replaceState({ + position: $rootScope.stackCursorPosition + }); + + $rootScope.stackCursorPosition++; + } + } + }); + } + } +}]) + +.directive('navBack', ['$window', function($window) { + return { + restrict: 'AC', + require: '^?navRouter', + link: function($scope, $element, $attr, navCtrl) { + var goBack = function() { + $window.history.back(); + }; + $element.bind('tap', goBack); + $element.bind('click', goBack); + + $scope.$on('$destroy', function() { + $element.unbind('tap', goBack); + $element.unbind('click', goBack); + }); + } + } +}]); + +})(); diff --git a/js/ext/angular/src/ionicAngular.js b/js/ext/angular/src/ionicAngular.js index 6cc73e061e..13d3326d68 100644 --- a/js/ext/angular/src/ionicAngular.js +++ b/js/ext/angular/src/ionicAngular.js @@ -16,6 +16,7 @@ angular.module('ionic.ui', [ 'ionic.ui.content', 'ionic.ui.tabs', 'ionic.ui.nav', + 'ionic.ui.navRouter', 'ionic.ui.header', 'ionic.ui.sideMenu', 'ionic.ui.slideBox', @@ -31,6 +32,7 @@ angular.module('ionic', [ // Angular deps 'ngAnimate', + 'ngRoute', 'ngTouch', 'ngSanitize' ]); diff --git a/js/ext/angular/test/navRouter.html b/js/ext/angular/test/navRouter.html new file mode 100644 index 0000000000..57be3332dd --- /dev/null +++ b/js/ext/angular/test/navRouter.html @@ -0,0 +1,119 @@ + + + + Nav Bars + + + + + + + + + + + + + + + + + + + +