From 7d076bd55b2117b3ac569ef41ae9f42bc56eca58 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Mon, 10 Mar 2014 22:14:55 -0500 Subject: [PATCH] feat(modal): Create a modal backdrop wrapper w/ internal modal directive, closes #605 --- js/ext/angular/src/directive/ionicModal.js | 21 +++++++++ js/ext/angular/src/service/ionicModal.js | 43 +++++++++++-------- .../angular/test/service/ionicModal.unit.js | 10 +++-- 3 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 js/ext/angular/src/directive/ionicModal.js diff --git a/js/ext/angular/src/directive/ionicModal.js b/js/ext/angular/src/directive/ionicModal.js new file mode 100644 index 00000000000..ebfb8391f5b --- /dev/null +++ b/js/ext/angular/src/directive/ionicModal.js @@ -0,0 +1,21 @@ +(function() { +'use strict'; + +angular.module('ionic.ui.modal', []) + +/* + * We don't document the ionModal directive, we instead document + * the $ionicModal service + */ +.directive('ionModal', [function() { + return { + restrict: 'E', + transclude: true, + replace: true, + template: '' + }; +}]); + +})(); diff --git a/js/ext/angular/src/service/ionicModal.js b/js/ext/angular/src/service/ionicModal.js index 4e9fa127046..0c09c3e1a32 100644 --- a/js/ext/angular/src/service/ionicModal.js +++ b/js/ext/angular/src/service/ionicModal.js @@ -1,31 +1,34 @@ -angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.service.platform', 'ngAnimate']) +angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.service.platform', 'ionic.ui.modal']) -.factory('$ionicModal', ['$rootScope', '$document', '$compile', '$animate', '$q', '$timeout', '$ionicPlatform', '$ionicTemplateLoader', function($rootScope, $document, $compile, $animate, $q, $timeout, $ionicPlatform, $ionicTemplateLoader) { +.factory('$ionicModal', ['$rootScope', '$document', '$compile', '$timeout', '$ionicPlatform', '$ionicTemplateLoader', + function( $rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader) { + var ModalView = ionic.views.Modal.inherit({ initialize: function(opts) { ionic.views.Modal.prototype.initialize.call(this, opts); this.animation = opts.animation || 'slide-in-up'; }, + // Show the modal show: function() { var self = this; - var element = angular.element(self.el); + var modalEl = angular.element(self.modalEl); - document.body.classList.add('modal-open'); + $document[0].body.classList.add('modal-open'); self._isShown = true; - if(!element.parent().length) { - self.el.classList.add(self.animation); + if(!self.el.parentElement) { + modalEl.addClass(self.animation); $document[0].body.appendChild(self.el); } - element.addClass('ng-enter active'); - element.removeClass('ng-leave ng-leave-active'); + modalEl.addClass('ng-enter active') + .removeClass('ng-leave ng-leave-active'); $timeout(function(){ - element.addClass('ng-enter-active'); + modalEl.addClass('ng-enter-active'); self.scope.$parent && self.scope.$parent.$broadcast('modal.shown'); }, 20); @@ -34,25 +37,26 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv }, 200); }, + // Hide the modal hide: function() { this._isShown = false; - var element = angular.element(this.el); + var modalEl = angular.element(this.modalEl); - element.addClass('ng-leave'); + modalEl.addClass('ng-leave'); $timeout(function(){ - element.addClass('ng-leave-active'); - element.removeClass('ng-enter ng-enter-active active'); + modalEl.addClass('ng-leave-active') + .removeClass('ng-enter ng-enter-active active'); }, 20); $timeout(function(){ - document.body.classList.remove('modal-open'); - }, 400); + $document[0].body.classList.remove('modal-open'); + }, 350); ionic.views.Modal.prototype.hide.call(this); - this.scope.$parent.$broadcast('modal.hidden'); + this.scope.$parent && this.scope.$parent.$broadcast('modal.hidden'); this._deregisterBackButton && this._deregisterBackButton(); }, @@ -61,12 +65,12 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv remove: function() { var self = this; self.hide(); - self.scope.$parent.$broadcast('modal.removed'); + self.scope.$parent && self.scope.$parent.$broadcast('modal.removed'); $timeout(function(){ self.scope.$destroy(); self.el && self.el.parentElement && self.el.parentElement.removeChild(self.el); - }, 1000); + }, 750); }, isShown: function() { @@ -79,9 +83,10 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv var scope = options.scope && options.scope.$new() || $rootScope.$new(true); // Compile the template - var element = $compile(templateString)(scope); + var element = $compile('' + templateString + '')(scope); options.el = element[0]; + options.modalEl = options.el.querySelector('.modal'); var modal = new ModalView(options); modal.scope = scope; diff --git a/js/ext/angular/test/service/ionicModal.unit.js b/js/ext/angular/test/service/ionicModal.unit.js index a9f7e7f45b4..e9f9f9eb6bc 100644 --- a/js/ext/angular/test/service/ionicModal.unit.js +++ b/js/ext/angular/test/service/ionicModal.unit.js @@ -18,8 +18,9 @@ describe('Ionic Modal', function() { var template = ''; var modalInstance = modal.fromTemplate(template); modalInstance.show(); - expect(modalInstance.el.classList.contains('modal')).toBe(true); - expect(modalInstance.el.classList.contains('slide-in-up')).toBe(true); + expect(modalInstance.el.classList.contains('modal-backdrop')).toBe(true); + expect(modalInstance.modalEl.classList.contains('modal')).toBe(true); + expect(modalInstance.modalEl.classList.contains('slide-in-up')).toBe(true); }); it('Should show for dynamic template', function() { @@ -30,8 +31,9 @@ describe('Ionic Modal', function() { var modalInstance = modal.fromTemplateUrl('modal.html', function(modalInstance) { done = true; modalInstance.show(); - expect(modalInstance.el.classList.contains('modal')).toBe(true); - expect(modalInstance.el.classList.contains('active')).toBe(true); + expect(modalInstance.el.classList.contains('modal-backdrop')).toBe(true); + expect(modalInstance.modalEl.classList.contains('modal')).toBe(true); + expect(modalInstance.modalEl.classList.contains('active')).toBe(true); }); timeout.flush();