diff --git a/js/angular/service/actionSheet.js b/js/angular/service/actionSheet.js index 5ed61d8ead..05a5b77451 100644 --- a/js/angular/service/actionSheet.js +++ b/js/angular/service/actionSheet.js @@ -107,9 +107,12 @@ function($rootScope, $document, $compile, $animate, $timeout, $ionicTemplateLoad }; // Support Android back button to close - scope.$deregisterBackButton = $ionicPlatform.registerBackButtonAction(function(){ - hideSheet(); - }, 300); + scope.$deregisterBackButton = $ionicPlatform.registerBackButtonAction( + function(){ + hideSheet(); + }, + PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET + ); scope.cancel = function() { hideSheet(true); diff --git a/js/angular/service/platform.js b/js/angular/service/platform.js index 1ef66589ba..8d35a22085 100644 --- a/js/angular/service/platform.js +++ b/js/angular/service/platform.js @@ -1,3 +1,6 @@ +var PLATFORM_BACK_BUTTON_PRIORITY_VIEW = 100; +var PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET = 300; +var PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 500; /** * @ngdoc service * @name $ionicPlatform diff --git a/js/angular/service/popup.js b/js/angular/service/popup.js index 38f14083b6..87a1fa08f1 100644 --- a/js/angular/service/popup.js +++ b/js/angular/service/popup.js @@ -98,16 +98,15 @@ var POPUP_TPL = */ IonicModule .factory('$ionicPopup', [ - '$animate', '$ionicTemplateLoader', '$ionicBackdrop', - '$log', '$q', '$timeout', '$rootScope', '$document', '$compile', -function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $rootScope, $document, $compile) { + '$ionicPlatform', +function($ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $document, $compile, $ionicPlatform) { //TODO allow this to be configured var config = { stackPushDelay: 50 @@ -348,6 +347,10 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $ro }); } + function onHardwareBackButton(e) { + popupStack[0] && popupStack[0].responseDeferred.resolve(); + } + function showPopup(options) { var popupPromise = $ionicPopup._createPopup(options); var previousPopup = popupStack[0]; @@ -363,6 +366,10 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $ro //Add popup-open & backdrop if this is first popup document.body.classList.add('popup-open'); $ionicBackdrop.retain(); + $ionicPopup._backButtonActionDone = $ionicPlatform.registerBackButtonAction( + onHardwareBackButton, + PLATFORM_BACK_BUTTON_PRIORITY_POPUP + ); } popupStack.unshift(popup); popup.show(); @@ -386,6 +393,7 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $ro //Remove popup-open & backdrop if this is last popup document.body.classList.remove('popup-open'); $ionicBackdrop.release(); + ($ionicPopup._backButtonActionDone || angular.noop)(); } return result; diff --git a/js/angular/service/viewService.js b/js/angular/service/viewService.js index 304ac1c044..769ab119af 100644 --- a/js/angular/service/viewService.js +++ b/js/angular/service/viewService.js @@ -79,7 +79,10 @@ function($rootScope, $state, $location, $document, $animate, $ionicPlatform, $io e.preventDefault(); return false; } - $ionicPlatform.registerBackButtonAction(onHardwareBackButton, 100); + $ionicPlatform.registerBackButtonAction( + onHardwareBackButton, + PLATFORM_BACK_BUTTON_PRIORITY_VIEW + ); }]) diff --git a/test/unit/angular/service/popup.unit.js b/test/unit/angular/service/popup.unit.js index e104433fe3..2caecb22f9 100644 --- a/test/unit/angular/service/popup.unit.js +++ b/test/unit/angular/service/popup.unit.js @@ -153,13 +153,21 @@ describe('$ionicPopup service', function() { afterEach(function() { document.body.classList.remove('popup-open'); }); - it('should add popup-open and retain backdrop if no previous popup', inject(function($ionicBackdrop, $timeout) { + + it('should add popup-open and retain backdrop and register back button action if no previous popup', inject(function($ionicBackdrop, $timeout, $ionicPlatform) { + spyOn($ionicPlatform, 'registerBackButtonAction').andReturn('actionReturn'); spyOn($ionicBackdrop, 'retain'); $ionicPopup.show(); $timeout.flush(); expect(angular.element(document.body).hasClass('popup-open')).toBe(true); expect($ionicBackdrop.retain).toHaveBeenCalled(); + expect($ionicPlatform.registerBackButtonAction).toHaveBeenCalledWith( + jasmine.any(Function), + PLATFORM_BACK_BUTTON_PRIORITY_POPUP + ); + expect($ionicPopup._backButtonActionDone).toBe('actionReturn'); })); + it('should hide previous popup if exists and not popup-open & backdrop', inject(function($ionicBackdrop, $timeout) { var previousPopup = { hide: jasmine.createSpy('hide') }; spyOn($ionicBackdrop, 'retain'); @@ -231,19 +239,21 @@ describe('$ionicPopup service', function() { expect(previousPopup.show).toHaveBeenCalled(); })); - it('should release backdrop and remove popup-open if no previous', inject(function($q, $timeout, $ionicBackdrop) { + it('should release backdrop and remove popup-open and deregister back if no previous', inject(function($q, $timeout, $ionicBackdrop, $ionicPlatform) { var fakePopup = { show: jasmine.createSpy('show'), remove: jasmine.createSpy('remove'), responseDeferred: $q.defer() }; - document.body.classList.add('popup-open'); + var backDoneSpy = jasmine.createSpy('backDone'); + spyOn($ionicPlatform, 'registerBackButtonAction').andReturn(backDoneSpy); spyOn($ionicBackdrop, 'release'); spyOn($ionicPopup, '_createPopup').andReturn($q.when(fakePopup)); $ionicPopup.show(); fakePopup.responseDeferred.resolve(); $timeout.flush(); expect($ionicBackdrop.release).toHaveBeenCalled(); + expect(backDoneSpy).toHaveBeenCalled(); expect(document.body.classList.contains('popup-open')).toBe(false); })); });