From b87bcb30c33fb577b41139c43089b2a864211d56 Mon Sep 17 00:00:00 2001 From: Andy Joslin Date: Tue, 29 Apr 2014 09:06:26 -0600 Subject: [PATCH] feat($ionicPopup): on android, make back button close popup Fixes #1222 --- js/angular/service/actionSheet.js | 9 ++++++--- js/angular/service/platform.js | 3 +++ js/angular/service/popup.js | 14 +++++++++++--- js/angular/service/viewService.js | 5 ++++- test/unit/angular/service/popup.unit.js | 16 +++++++++++++--- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/js/angular/service/actionSheet.js b/js/angular/service/actionSheet.js index 5ed61d8eadc..05a5b77451e 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 1ef66589baa..8d35a22085c 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 38f14083b65..87a1fa08f1c 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 304ac1c0444..769ab119af3 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 e104433fe3c..2caecb22f97 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); })); });