refactor($ionicPopup): add close() to returned promise, change closing

BREAKING CHANGE: $ionicPopup.show()'s button onTap function has changed.

When using `$ionicPopup.show()`, previously a button's onTap function
would only result in closing the popup and resolving the promise if the
 `onTap(event)` function returned a truthy value.

Now, a button's onTap event will *always* close the popup and resolve
the popup's promise, no matter the return value, by default. The only
way to prevent the popup from closing is to call
`event.preventDefault()`.

Change your code from this:

```js
$ionicPopup.show({
  buttons: [{
    onTap: function(event) {
      if (!shouldClosePopup) {
        return false;
      }
    }
  }]
});
```

To this:

```js
$ionicPopup.show({
  buttons: [{
    onTap: function(event) {
      if (!shouldClosePopup) {
        event.preventDefault();
      }
    }
  }]
});
```
This commit is contained in:
Andy Joslin
2014-04-08 08:45:28 -06:00
parent 98e7e3df46
commit cb1a5f6228
4 changed files with 227 additions and 223 deletions

View File

@@ -3,11 +3,11 @@ var TPL_LOADING =
'<div class="loading ng-hide" ng-bind-html="html">' +
'</div>';
var HIDE_DEPRECATED = '$ionicLoading instance.hide() has been deprecated. Use $ionicLoading.hide().';
var SHOW_DEPRECATED = '$ionicLoading instance.show() has been deprecated. Use $ionicLoading.show().';
var SET_DEPRECATED = '$ionicLoading instance.setContent() has been deprecated. Use $ionicLoading.show({ content: \'my content\' }).';
var SHOW_DELAY_DEPRECATED = '$ionicLoading options.showDelay has been deprecated. Use options.delay instead.';
var SHOW_BACKDROP_DEPRECATED = '$ionicLoading options.showBackdrop has been deprecated. Use options.noBackdrop instead.';
var HIDE_LOADING_DEPRECATED = '$ionicLoading instance.hide() has been deprecated. Use $ionicLoading.hide().';
var SHOW_LOADING_DEPRECATED = '$ionicLoading instance.show() has been deprecated. Use $ionicLoading.show().';
var SET_LOADING_DEPRECATED = '$ionicLoading instance.setContent() has been deprecated. Use $ionicLoading.show({ content: \'my content\' }).';
var SHOW_DELAY_LOADING_DEPRECATED = '$ionicLoading options.showDelay has been deprecated. Use options.delay instead.';
var SHOW_BACKDROP_LOADING_DEPRECATED = '$ionicLoading options.showBackdrop has been deprecated. Use options.noBackdrop instead.';
angular.module('ionic.service.loading', [])
@@ -97,9 +97,16 @@ function($animate, $document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q
}
var el = this.element;
var scope = this.scope;
ionic.requestAnimationFrame(function() {
$animate.removeClass(el, 'ng-hide');
//Fix for ios: if we center the element twice, it always gets
//position right. Otherwise, it doesn't
ionic.DomUtil.centerElementByMargin(el[0]);
//One frame after it's visible, position it
ionic.requestAnimationFrame(function() {
ionic.DomUtil.centerElementByMargin(el[0]);
});
});
this.isShown = true;
@@ -123,8 +130,8 @@ function($animate, $document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q
function showLoader(options) {
options || (options = {});
deprecated.field(SHOW_DELAY_DEPRECATED, $log.warn, options, 'showDelay', options.showDelay);
deprecated.field(SHOW_BACKDROP_DEPRECATED, $log.warn, options, 'showBackdrop', options.showBackdrop);
deprecated.field(SHOW_DELAY_LOADING_DEPRECATED, $log.warn, options, 'showDelay', options.showDelay);
deprecated.field(SHOW_BACKDROP_LOADING_DEPRECATED, $log.warn, options, 'showBackdrop', options.showBackdrop);
$timeout(getLoader, options.delay || options.showDelay || 0)
.then(function(loader) {
@@ -132,11 +139,11 @@ function($animate, $document, $ionicTemplateLoader, $ionicBackdrop, $timeout, $q
});
return {
hide: deprecated.method(HIDE_DEPRECATED, $log.warn, hideLoader),
show: deprecated.method(SHOW_DEPRECATED, $log.warn, function() {
hide: deprecated.method(HIDE_LOADING_DEPRECATED, $log.warn, hideLoader),
show: deprecated.method(SHOW_LOADING_DEPRECATED, $log.warn, function() {
showLoader(options);
}),
setContent: deprecated.method(SET_DEPRECATED, $log.warn, function(content) {
setContent: deprecated.method(SET_LOADING_DEPRECATED, $log.warn, function(content) {
getLoader().then(function(loader) {
loader.scope.html = content;
});

View File

@@ -12,6 +12,8 @@ var TPL_POPUP =
'</div>' +
'</div>';
var CONTENT_POPUP_DEPRECATED = '$ionicPopup options.content has been deprecated. Use options.template instead.';
angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
/**
@@ -22,102 +24,81 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
* @codepen zkmhJ
* @description
*
* The Ionic Popup service makes it easy to programmatically create and show popup
* windows that require the user to respond in order to continue:
* The Ionic Popup service allows programmatically creating and showing popup
* windows that require the user to respond in order to continue.
*
* The popup system has support for nicer versions of the built in `alert()` `prompt()` and `confirm()` functions
* you are used to in the browser, but with more powerful support for customizing input types in the case of
* prompt, or customizing the look of the window.
*
* But the true power of the Popup is when a built-in popup just won't cut it. Luckily, the popup window
* has full support for arbitrary popup content, and a simple promise-based system for returning data
* entered by the user.
* The popup system has support for more flexible versions of the built in `alert()`, `prompt()`,
* and `confirm()` functions that users are used to, in addition to allowing popups with completely
* custom content and look.
*
* @usage
* To trigger a Popup in your code, use the $ionicPopup service in your angular controllers:
* A few basic examples, see below for details about all of the options available.
*
* ```js
* angular.module('mySuperApp', ['ionic'])
* .controller(function($scope, $ionicPopup) {
* .controller(function($scope, $ionicPopup, $timeout) {
*
* // Triggered on a button click, or some other target
$scope.showPopup = function() {
$scope.data = {}
// An elaborate, custom popup
$ionicPopup.show({
templateUrl: 'popup-template.html',
title: 'Enter Wi-Fi Password',
subTitle: 'Please use normal things',
scope: $scope,
buttons: [
{ text: 'Cancel', onTap: function(e) { return true; } },
{
text: '<b>Save</b>',
type: 'button-positive',
onTap: function(e) {
return $scope.data.wifi;
}
},
]
}).then(function(res) {
console.log('Tapped!', res);
}, function(err) {
console.log('Err:', err);
}, function(popup) {
// If you need to access the popup directly, do it in the notify method
// This is also where you can programmatically close the popup:
// popup.close();
});
// A confirm dialog
$scope.showConfirm = function() {
$ionicPopup.confirm({
title: 'Consume Ice Cream',
content: 'Are you sure you want to eat this ice cream?'
}).then(function(res) {
if(res) {
console.log('You are sure');
} else {
console.log('You are not sure');
}
});
};
// A prompt dialog
$scope.showPrompt = function() {
$ionicPopup.prompt({
title: 'ID Check',
content: 'What is your name?'
}).then(function(res) {
console.log('Your name is', res);
});
};
// A prompt with password input dialog
$scope.showPasswordPrompt = function() {
$ionicPopup.prompt({
title: 'Password Check',
content: 'Enter your secret password',
inputType: 'password',
inputPlaceholder: 'Your password'
}).then(function(res) {
console.log('Your password is', res);
});
};
// An alert dialog
$scope.showAlert = function() {
$ionicPopup.alert({
title: 'Don\'t eat that!',
content: 'It might taste good'
}).then(function(res) {
console.log('Thank you for not eating my delicious ice cream cone');
});
};
};
});
```
* $scope.showPopup = function() {
* $scope.data = {}
*
* // An elaborate, custom popup
* var myPopup = $ionicPopup.show({
* template: '<input type="password" ng-model="data.wifi">',
* title: 'Enter Wi-Fi Password',
* subTitle: 'Please use normal things',
* scope: $scope,
* buttons: [
* { text: 'Cancel' },
* {
* text: '<b>Save</b>',
* type: 'button-positive',
* onTap: function(e) {
* if (!$scope.data.wifi) {
* //don't allow the user to close unless he enters wifi password
* e.preventDefault();
* } else {
* return $scope.data.wifi;
* }
* }
* },
* ]
* });
* myPopup.then(function(res) {
* console.log('Tapped!', res);
* });
* $timeout(function() {
* myPopup.close(); //close the popup after 3 seconds for some reason
* }, 3000);
*
* // A confirm dialog
* $scope.showConfirm = function() {
* var confirmPopup = $ionicPopup.confirm({
* title: 'Consume Ice Cream',
* template: 'Are you sure you want to eat this ice cream?'
* });
* confirmPopup.then(function(res) {
* if(res) {
* console.log('You are sure');
* } else {
* console.log('You are not sure');
* }
* });
* };
*
* // An alert dialog
* $scope.showAlert = function() {
* var alertPopup = $ionicPopup.alert({
* title: 'Don\'t eat that!',
* template: 'It might taste good'
* });
* alertPopup.then(function(res) {
* console.log('Thank you for not eating my delicious ice cream cone');
* });
* };
* };
*});
*```
*/
@@ -125,12 +106,13 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
'$animate',
'$ionicTemplateLoader',
'$ionicBackdrop',
'$log',
'$q',
'$timeout',
'$rootScope',
'$document',
'$compile',
function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScope, $document, $compile) {
function($animate, $ionicTemplateLoader, $ionicBackdrop, $log, $q, $timeout, $rootScope, $document, $compile) {
//TODO allow this to be configured
var config = {
stackPushDelay: 50
@@ -139,68 +121,71 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
var $ionicPopup = {
/**
* @ngdoc method
* @description Show a complex popup. This is the master show function for all popups.
* @description
* Show a complex popup. This is the master show function for all popups.
*
* A complex popup has a `buttons` array, with each button having a `text` and `type`
* field, in addition to an `onTap` function. The `onTap` function, called when
* the correspondingbutton on the popup is tapped, will by default close the popup
* and resolve the popup promise with its return value. If you wish to prevent the
* default and keep the popup open on button tap, call `event.preventDefault()` on the
* passed in tap event. Details below.
*
* @name $ionicPopup#show
* @param {data} object The options for showing a popup, of the form:
* @returns {Promise} an Angular promise which resolves when the user enters the correct data, and also sends the constructed popup in the notify function (for programmatic closing, as shown in the example above).
* @param {object} options The options for the new popup, of the form:
*
* ```
* {
* content: '', // String. The content of the popup
* title: '', // String. The title of the popup
* subTitle: '', // String (optional). The sub-title of the popup
* templateUrl: '', // URL String (optional). The URL of a template to load as the content (instead of the `content` field)
* scope: null, // Scope (optional). A scope to apply to the popup content (for using ng-model in a template, for example)
* buttons: [{
* title: '', // String. The title of the popup.
* subTitle: '', // String (optional). The sub-title of the popup.
* template: '', // String (optional). The html template to place in the popup body.
* templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
* scope: null, // Scope (optional). A scope to link to the popup content.
* buttons: [{ //Array[Object] (optional). Buttons to place in the popup footer.
* text: 'Cancel',
* type: 'button-default',
* onTap: function(e) {
* // e.preventDefault() or giving no return value will stop the popup
* // from closing on tap
* // e.preventDefault() will stop the popup from closing when tapped.
* e.preventDefault();
* }
* }, {
* text: 'OK',
* type: 'button-positive',
* onTap: function(e) {
* // When the user taps one of the buttons, you need to return the
* // Data you want back to the popup service which will then resolve
* // the promise waiting for a response.
* // Returning a value will cause the promise to resolve with the given value.
* return scope.data.response;
* }
* }]
* }
* ```
*
* @returns {object} A promise which is resolved when the popup is closed. Has an additional
* `close` function, which can be used to programmatically close the popup.
*/
show: showPopup,
/**
* @ngdoc method
* @name $ionicPopup#alert
* @description show a simple popup with one button that the user has to tap
* @description Show a simple alert popup with a message and one button that the user can
* tap to close the popup.
*
* Show a simple alert dialog
*
* ```javascript
* $ionicPopup.alert({
* title: 'Hey!',
* content: 'Don\'t do that!'
* }).then(function(res) {
* // Accepted
* });
* ```
*
* @returns {Promise} that resolves when the alert is accepted
* @param {data} object The options for showing an alert, of the form:
* @param {object} options The options for showing the alert, of the form:
*
* ```
* {
* content: '', // String. The content of the popup
* title: '', // String. The title of the popup
* okText: '', // String. The text of the OK button
* okType: '', // String (default: button-positive). The type of the OK button
* title: '', // String. The title of the popup.
* subTitle: '', // String (optional). The sub-title of the popup.
* template: '', // String (optional). The html template to place in the popup body.
* templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
* okText: '', // String (default: 'OK'). The text of the OK button.
* okType: '', // String (default: 'button-positive'). The type of the OK button.
* }
* ```
*
* @returns {object} A promise which is resolved when the popup is closed. Has one additional
* function `close`, which can be called with any value to programmatically close the popup
* with the given value.
*/
alert: showAlert,
@@ -208,69 +193,69 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
* @ngdoc method
* @name $ionicPopup#confirm
* @description
* Show a simple confirm popup with a cancel and accept button:
* Show a simple confirm popup with a Cancel and OK button.
*
* ```javascript
* $ionicPopup.confirm({
* title: 'Consume Ice Cream',
* content: 'Are you sure you want to eat this ice cream?'
* }).then(function(res) {
* if(res) {
* console.log('You are sure');
* } else {
* console.log('You are not sure');
* }
* });
* ```
* Resolves the promise with true if the user presses the OK button, and false if the
* user presses the Cancel button.
*
* @returns {Promise} that resolves with the chosen option
* @param {data} object The options for showing a confirm dialog, of the form:
* @param {object} options The options for showing the confirm popup, of the form:
*
* ```
* {
* content: '', // String. The content of the popup
* title: '', // String. The title of the popup
* cancelText: '', // String. The text of the Cancel button
* cancelType: '', // String (default: button-default). The type of the kCancel button
* okText: '', // String. The text of the OK button
* okType: '', // String (default: button-positive). The type of the OK button
* title: '', // String. The title of the popup.
* subTitle: '', // String (optional). The sub-title of the popup.
* template: '', // String (optional). The html template to place in the popup body.
* templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
* cancelText: '', // String (default: 'Cancel'). The text of the Cancel button.
* cancelType: '', // String (default: 'button-default'). The type of the Cancel button.
* okText: '', // String (default: 'OK'). The text of the OK button.
* okType: '', // String (default: 'button-positive'). The type of the OK button.
* }
* ```
*
* @returns {object} A promise which is resolved when the popup is closed. Has one additional
* function `close`, which can be called with any value to programmatically close the popup
* with the given value.
*/
confirm: showConfirm,
/**
* @ngdoc method
* @name $ionicPopup#prompt
* @description show a simple prompt dialog.
* @description Show a simple prompt popup, which has an input, OK button, and Cancel button.
* Resolves the promise with the value of the input if the user presses OK, and with undefined
* if the user presses Cancel.
*
* ```javascript
* $ionicPopup.prompt({
* title: 'Password Check',
* content: 'Enter your secret password',
* template: 'Enter your secret password',
* inputType: 'password',
* inputPlaceholder: 'Your password'
* }).then(function(res) {
* console.log('Your password is', res);
* });
* ```
*
* @returns {Promise} that resolves with the entered data
* @param {data} object The options for showing a prompt dialog, of the form:
* @param {object} options The options for showing the prompt popup, of the form:
*
* ```
* {
* content: // String. The content of the popup
* title: // String. The title of the popup
* subTitle: // String. The sub title of the popup
* inputType: // String (default: "text"). The type of input to use
* inputPlaceholder: // String (default: ""). A placeholder to use for the input.
* cancelText: // String. The text of the Cancel button
* cancelType: // String (default: button-default). The type of the kCancel button
* okText: // String. The text of the OK button
* okType: // String (default: button-positive). The type of the OK button
* title: '', // String. The title of the popup.
* subTitle: '', // String (optional). The sub-title of the popup.
* template: '', // String (optional). The html template to place in the popup body.
* templateUrl: '', // String (optional). The URL of an html template to place in the popup body.
* inputType: // String (default: 'text'). The type of input to use
* inputPlaceholder: // String (default: ''). A placeholder to use for the input.
* cancelText: // String (default: 'Cancel'. The text of the Cancel button.
* cancelType: // String (default: 'button-default'). The type of the Cancel button.
* okText: // String (default: 'OK'). The text of the OK button.
* okType: // String (default: 'button-positive'). The type of the OK button.
* }
* ```
*
* @returns {object} A promise which is resolved when the popup is closed. Has one additional
* function `close`, which can be called with any value to programmatically close the popup
* with the given value.
*/
prompt: showPrompt,
/**
@@ -289,6 +274,8 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
buttons: [],
}, options || {});
deprecated.field(CONTENT_POPUP_DEPRECATED, $log.warn, options, 'content', options.content);
var popupPromise = $ionicTemplateLoader.compile({
template: TPL_POPUP,
scope: options.scope && options.scope.$new(),
@@ -305,7 +292,6 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
var responseDeferred = $q.defer();
self.responseDeferred = responseDeferred;
self.responseDeferred.notify(self);
//Can't ng-bind-html for popup-body because it can be insecure html
//(eg an input in case of prompt)
@@ -317,17 +303,16 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
body.remove();
}
angular.extend(self.scope, {
title: options.title,
buttons: options.buttons,
subTitle: options.subTitle,
$buttonTapped: function(button, event) {
var result = button.onTap && button.onTap(event);
event = event.originalEvent || event;
var result = (button.onTap || angular.noop)(event);
event = event.originalEvent || event; //jquery events
if (event.defaultPrevented || angular.isDefined(result)) {
responseDeferred.resolve(event.defaultPrevented ? undefined : result);
if (!event.defaultPrevented) {
responseDeferred.resolve(result);
}
}
});
@@ -339,7 +324,13 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
self.element.removeClass('popup-hidden');
self.element.addClass('popup-showing active');
focusLastButton(self.element);
//Fix for ios: if we center the element twice, it always gets
//position right. Otherwise, it doesn't
ionic.DomUtil.centerElementByMargin(self.element[0]);
//One frame after it's visible, position it
ionic.requestAnimationFrame(function() {
ionic.DomUtil.centerElementByMargin(self.element[0]);
});
});
self.isShown = true;
@@ -355,10 +346,14 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
self.isShown = false;
};
self.remove = function() {
if (self.removed) return;
self.hide(function() {
self.element.remove();
self.scope.$destroy();
});
self.removed = true;
};
return self;
@@ -373,7 +368,7 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
previousPopup.hide();
}
return $timeout(angular.noop, previousPopup ? config.stackPushDelay : 0)
var resultPromise = $timeout(angular.noop, previousPopup ? config.stackPushDelay : 0)
.then(function() { return popupPromise; })
.then(function(popup) {
if (!previousPopup) {
@@ -384,8 +379,16 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
popupStack.unshift(popup);
popup.show();
//DEPRECATED: notify the promise with an object with a close method
popup.responseDeferred.notify({
close: resultPromise.close
});
return popup.responseDeferred.promise.then(function(result) {
popupStack.shift();
var index = popupStack.indexOf(popup);
if (index !== -1) {
popupStack.splice(index, 1);
}
popup.remove();
var previousPopup = popupStack[0];
@@ -400,6 +403,17 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
return result;
});
});
function close(result) {
popupPromise.then(function(popup) {
if (!popup.removed) {
popup.responseDeferred.resolve(result);
}
});
}
resultPromise.close = close;
return resultPromise;
}
function focusLastButton(element) {
@@ -411,9 +425,7 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
}
function showAlert(opts) {
return showPopup({
content: opts.content,
title: opts.title,
return showPopup( angular.extend({
buttons: [{
text: opts.okText || 'OK',
type: opts.okType || 'button-positive',
@@ -421,13 +433,11 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
return true;
}
}]
});
}, opts || {}) );
}
function showConfirm(opts) {
return showPopup({
content: opts.content || '',
title: opts.title || '',
return showPopup( angular.extend({
buttons: [{
text: opts.cancelText || 'Cancel' ,
type: opts.cancelType || 'button-default',
@@ -437,17 +447,15 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
type: opts.okType || 'button-positive',
onTap: function(e) { return true; }
}]
});
}, opts || {}) );
}
function showPrompt(opts) {
var scope = $rootScope.$new(true);
scope.data = {};
return showPopup({
content: opts.content ||
'<input ng-model="data.response" type="' + (opts.inputType || 'text') + '" placeholder="' + (opts.inputPlaceholder || '') + '">',
title: opts.title || '',
subTitle: opts.subTitle || '',
return showPopup( angular.extend({
template: '<input ng-model="data.response" type="' + (opts.inputType || 'text') +
'" placeholder="' + (opts.inputPlaceholder || '') + '">',
scope: scope,
buttons: [{
text: opts.cancelText || 'Cancel',
@@ -457,10 +465,10 @@ function($animate, $ionicTemplateLoader, $ionicBackdrop, $q, $timeout, $rootScop
text: opts.okText || 'OK',
type: opts.okType || 'button-positive',
onTap: function(e) {
return scope.data.response;
return scope.data.response || '';
}
}]
});
}, opts || {}) );
}
}]);

View File

@@ -55,12 +55,8 @@ describe('$ionicPopup service', function() {
describe('$buttonTapped', function() {
var popup;
var button;
var event;
beforeEach(function() {
popup = TestUtil.unwrapPromise($ionicPopup._createPopup());
button = { onTap: jasmine.createSpy('onTap') };
event = {};
spyOn(popup.responseDeferred, 'resolve');
});
it('should call button.onTap with event', function() {
@@ -69,20 +65,20 @@ describe('$ionicPopup service', function() {
popup.scope.$buttonTapped(button, event);
expect(button.onTap).toHaveBeenCalledWith(event);
});
it('should do nothing if no result & not defaultPrevented', function() {
popup.scope.$buttonTapped(button, event);
expect(popup.responseDeferred.resolve).not.toHaveBeenCalled();
});
it('should resolve if defaultPrevented', function() {
event.defaultPrevented = true;
popup.scope.$buttonTapped(button, event);
expect(popup.responseDeferred.resolve).toHaveBeenCalledWith(undefined);
});
it('should resolve with result if result', function() {
button.onTap = jasmine.createSpy('onTap').andReturn('123');
popup.scope.$buttonTapped(button, event);
it('should resolve with return value from button.onTap', function() {
popup.scope.$buttonTapped({
onTap: function() { return '123' }
}, {});
expect(popup.responseDeferred.resolve).toHaveBeenCalledWith('123');
});
it('should not resolve if defaultPrevented', function() {
popup.scope.$buttonTapped({
onTap: function(){}
}, {
defaultPrevented: true
});
expect(popup.responseDeferred.resolve).not.toHaveBeenCalled();
});
});
describe('show', function() {
@@ -140,7 +136,7 @@ describe('$ionicPopup service', function() {
});
describe('show()', function() {
describe('$ionicPopup.showPopup()', function() {
afterEach(function() {
document.body.classList.remove('popup-open');
});
@@ -177,6 +173,16 @@ describe('$ionicPopup service', function() {
expect(fakePopup.show).toHaveBeenCalled();
}));
it('should have close function which resolves promise with argument', inject(function($ionicPopup, $q, $rootScope) {
var popup = TestUtil.unwrapPromise($ionicPopup._createPopup());
spyOn($ionicPopup, '_createPopup').andReturn($q.when(popup));
var result = $ionicPopup.show();
spyOn(popup.responseDeferred, 'resolve');
result.close('foobar');
$rootScope.$apply();
expect(popup.responseDeferred.resolve).toHaveBeenCalledWith('foobar');
}));
it('should after timeout and resolve remove popup, then return result', inject(function($ionicPopup, $timeout, $q, $rootScope) {
var fakePopup = {
show: jasmine.createSpy('show'),

View File

@@ -89,20 +89,3 @@
pointer-events: auto;
}
}
.popup-backdrop {
@include animation-name(fadeIn);
@include animation-duration($popup-backdrop-fadein-duration);
@include animation-timing-function(linear);
@include animation-fill-mode(both);
position: fixed;
top: 0;
left: 0;
z-index: $z-index-popup-backdrop;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.4);
}