angular-modal-service
Advanced tools
Comparing version 0.6.9 to 0.6.10
{ | ||
"name": "angular-modal-service", | ||
"version": "0.6.9", | ||
"version": "0.6.10", | ||
"homepage": "https://github.com/dwmkerr/angular-modal-service", | ||
@@ -38,3 +38,6 @@ "authors": [ | ||
"jquery": "~2.1.3" | ||
}, | ||
"resolutions": { | ||
"angular": "1.4.9" | ||
} | ||
} |
@@ -0,1 +1,6 @@ | ||
## v0.6.10 | ||
* Added support for using a custom parent scope for the controller scope, via the `scope` option. | ||
* Fixed a bug with controllerAs vs `controller as`. | ||
## v0.6.6 | ||
@@ -2,0 +7,0 @@ |
@@ -13,4 +13,4 @@ // angularModalService.js | ||
module.factory('ModalService', ['$document', '$compile', '$controller', '$http', '$rootScope', '$q', '$templateCache', | ||
function($document, $compile, $controller, $http, $rootScope, $q, $templateCache) { | ||
module.factory('ModalService', ['$animate', '$document', '$compile', '$controller', '$http', '$rootScope', '$q', '$templateRequest', '$timeout', | ||
function($animate, $document, $compile, $controller, $http, $rootScope, $q, $templateRequest, $timeout) { | ||
@@ -29,9 +29,8 @@ // Get the body of the document, we'll add the modal to this. | ||
var deferred = $q.defer(); | ||
if(template) { | ||
if (template) { | ||
deferred.resolve(template); | ||
} else if(templateUrl) { | ||
// Get the template, using the $templateCache. | ||
$http.get(templateUrl, {cache: $templateCache}) | ||
.then(function(result) { | ||
deferred.resolve(result.data); | ||
} else if (templateUrl) { | ||
$templateRequest(templateUrl, true) | ||
.then(function(template) { | ||
deferred.resolve(template); | ||
}, function(error) { | ||
@@ -46,2 +45,13 @@ deferred.reject(error); | ||
// Adds an element to the DOM as the last child of its container | ||
// like append, but uses $animate to handle animations. Returns a | ||
// promise that is resolved once all animation is complete. | ||
var appendChild = function(parent, child) { | ||
var children = parent.children(); | ||
if (children.length > 0) { | ||
return $animate.enter(child, parent, children[children.length - 1]); | ||
} | ||
return $animate.enter(child, parent); | ||
}; | ||
self.showModal = function(options) { | ||
@@ -54,3 +64,3 @@ | ||
var controllerName = options.controller; | ||
if(!controllerName) { | ||
if (!controllerName) { | ||
deferred.reject("No controller has been specified."); | ||
@@ -65,3 +75,3 @@ return deferred.promise; | ||
// Create a new scope for the modal. | ||
var modalScope = $rootScope.$new(); | ||
var modalScope = (options.scope || $rootScope).$new(); | ||
@@ -75,24 +85,31 @@ // Create the inputs object to the controller - this will include | ||
var closeDeferred = $q.defer(); | ||
var closedDeferred = $q.defer(); | ||
var inputs = { | ||
$scope: modalScope, | ||
close: function(result, delay) { | ||
if(delay === undefined || delay === null) delay = 0; | ||
window.setTimeout(function() { | ||
if (delay === undefined || delay === null) delay = 0; | ||
$timeout(function() { | ||
// Resolve the 'close' promise. | ||
closeDeferred.resolve(result); | ||
// We can now clean up the scope and remove the element from the DOM. | ||
modalScope.$destroy(); | ||
modalElement.remove(); | ||
// Let angular remove the element and wait for animations to finish. | ||
$animate.leave(modalElement) | ||
.then(function () { | ||
// Resolve the 'closed' promise. | ||
closedDeferred.resolve(result); | ||
// Unless we null out all of these objects we seem to suffer | ||
// from memory leaks, if anyone can explain why then I'd | ||
// be very interested to know. | ||
inputs.close = null; | ||
deferred = null; | ||
closeDeferred = null; | ||
modal = null; | ||
inputs = null; | ||
modalElement = null; | ||
modalScope = null; | ||
// We can now clean up the scope | ||
modalScope.$destroy(); | ||
// Unless we null out all of these objects we seem to suffer | ||
// from memory leaks, if anyone can explain why then I'd | ||
// be very interested to know. | ||
inputs.close = null; | ||
deferred = null; | ||
closeDeferred = null; | ||
modal = null; | ||
inputs = null; | ||
modalElement = null; | ||
modalScope = null; | ||
}); | ||
}, delay); | ||
@@ -103,3 +120,3 @@ } | ||
// If we have provided any inputs, pass them to the controller. | ||
if(options.inputs) angular.extend(inputs, options.inputs); | ||
if (options.inputs) angular.extend(inputs, options.inputs); | ||
@@ -113,14 +130,16 @@ // Compile then link the template element, building the actual element. | ||
// Create the controller, explicitly specifying the scope to use. | ||
var modalController = $controller(options.controller, inputs); | ||
var controllerObjBefore = modalScope[options.controllerAs]; | ||
var modalController = $controller(options.controller, inputs, false, options.controllerAs); | ||
if(options.controllerAs){ | ||
modalScope[options.controllerAs] = modalController ; | ||
if (options.controllerAs && controllerObjBefore) { | ||
angular.extend(modalController, controllerObjBefore); | ||
} | ||
// Finally, append the modal to the dom. | ||
if (options.appendElement) { | ||
// append to custom append element | ||
options.appendElement.append(modalElement); | ||
appendChild(options.appendElement, modalElement); | ||
} else { | ||
// append to body when no custom append element is specified | ||
body.append(modalElement); | ||
appendChild(body, modalElement); | ||
} | ||
@@ -133,3 +152,4 @@ | ||
element: modalElement, | ||
close: closeDeferred.promise | ||
close: closeDeferred.promise, | ||
closed: closedDeferred.promise | ||
}; | ||
@@ -136,0 +156,0 @@ |
@@ -1,3 +0,3 @@ | ||
/*angular-modal-service v0.6.8 - https://github.com/dwmkerr/angular-modal-service */ | ||
!function(){"use strict";var e=angular.module("angularModalService",[]);e.factory("ModalService",["$document","$compile","$controller","$http","$rootScope","$q","$templateCache",function(e,n,l,o,t,r,c){function a(){var e=this,a=function(e,n){var l=r.defer();return e?l.resolve(e):n?o.get(n,{cache:c}).then(function(e){l.resolve(e.data)},function(e){l.reject(e)}):l.reject("No template or templateUrl has been specified."),l.promise};e.showModal=function(e){var o=r.defer(),c=e.controller;return c?(a(e.template,e.templateUrl).then(function(c){var a=t.$new(),i=r.defer(),s={$scope:a,close:function(e,n){(void 0===n||null===n)&&(n=0),window.setTimeout(function(){i.resolve(e),a.$destroy(),d.remove(),s.close=null,o=null,i=null,m=null,s=null,d=null,a=null},n)}};e.inputs&&angular.extend(s,e.inputs);var p=n(c),d=p(a);s.$element=d;var f=l(e.controller,s);e.controllerAs&&(a[e.controllerAs]=f),e.appendElement?e.appendElement.append(d):u.append(d);var m={controller:f,scope:a,element:d,close:i.promise};o.resolve(m)}).then(null,function(e){o.reject(e)}),o.promise):(o.reject("No controller has been specified."),o.promise)}}var u=e.find("body");return new a}])}(); | ||
/*angular-modal-service v0.6.9 - https://github.com/dwmkerr/angular-modal-service */ | ||
!function(){"use strict";var e=angular.module("angularModalService",[]);e.factory("ModalService",["$animate","$document","$compile","$controller","$http","$rootScope","$q","$templateRequest","$timeout",function(e,n,r,t,l,o,c,u,a){function i(){var n=this,l=function(e,n){var r=c.defer();return e?r.resolve(e):n?u(n,!0).then(function(e){r.resolve(e)},function(e){r.reject(e)}):r.reject("No template or templateUrl has been specified."),r.promise},i=function(n,r){var t=n.children();return t.length>0?e.enter(r,n,t[t.length-1]):e.enter(r,n)};n.showModal=function(n){var u=c.defer(),p=n.controller;return p?(l(n.template,n.templateUrl).then(function(l){var p=(n.scope||o).$new(),d=c.defer(),f=c.defer(),m={$scope:p,close:function(n,r){(void 0===r||null===r)&&(r=0),a(function(){d.resolve(n),e.leave($).then(function(){f.resolve(n),p.$destroy(),m.close=null,u=null,d=null,j=null,m=null,$=null,p=null})},r)}};n.inputs&&angular.extend(m,n.inputs);var v=r(l),$=v(p);m.$element=$;var h=p[n.controllerAs],g=t(n.controller,m,!1,n.controllerAs);n.controllerAs&&h&&angular.extend(g,h),n.appendElement?i(n.appendElement,$):i(s,$);var j={controller:g,scope:p,element:$,close:d.promise,closed:f.promise};u.resolve(j)}).then(null,function(e){u.reject(e)}),u.promise):(u.reject("No controller has been specified."),u.promise)}}var s=n.find("body");return new i}])}(); | ||
//# sourceMappingURL=angular-modal-service.min.js.map |
{ | ||
"name": "angular-modal-service", | ||
"version": "0.6.9", | ||
"version": "0.6.10", | ||
"description": "AngularJS Service for showing Modals and Popups", | ||
@@ -5,0 +5,0 @@ "main": "./dst/angular-modal-service.js", |
@@ -24,3 +24,9 @@ angular-modal-service | ||
``` | ||
or npm | ||
``` | ||
npm install angular-modal-service | ||
``` | ||
Then reference the minified script: | ||
@@ -41,3 +47,3 @@ | ||
```js | ||
app.controller('SampleController', function($scope, ModalService) { | ||
app.controller('SampleController', ["$scope", "ModalService", function($scope, ModalService) { | ||
@@ -62,3 +68,3 @@ $scope.showAModal = function() { | ||
}); | ||
}]); | ||
``` | ||
@@ -68,4 +74,6 @@ | ||
and the controller for it is created. The promise returns a `modal` object which contains the | ||
element created, the controller, the scope and a `close` promise which is resolved when the | ||
modal is closed - this `close` promise provides the result of the modal close function. | ||
element created, the controller, the scope and two promises: `close` and `closed`. Both are | ||
resolved to the result of the modal close function, but `close` is resolved as soon as the | ||
modal close function is called, while `closed` is only resolved once the modal has finished | ||
animating and has been completely removed from the DOM. | ||
@@ -87,6 +95,6 @@ The modal controller can be any controller that you like, just remember that it is always | ||
The `close` function is automatically injected to the modal controller and takes the result | ||
object (which is passed to the `close` promise used by the caller). It can take an optional | ||
second parameter, the number of milliseconds to wait before destroying the DOM element. This | ||
is so that you can have a delay before destroying the DOM element if you are animating the | ||
closure. | ||
object (which is passed to the `close` and `closed` promises used by the caller). It can | ||
take an optional second parameter, the number of milliseconds to wait before destroying the | ||
DOM element. This is so that you can have a delay before destroying the DOM element if you | ||
are animating the closure. | ||
@@ -118,3 +126,5 @@ Now just make sure the `close` function is called by your modal controller when the modal | ||
You can also provide a controller function directly to the modal, with or without the controllerAs attribute : | ||
You can also provide a controller function directly to the modal, with or without the `controllerAs` attribute. | ||
But if you provide `controller` attribute with `as` syntax and `controllerAs` attribute together, `controllerAs` | ||
will have high priority. | ||
@@ -135,3 +145,3 @@ ```js | ||
* `controller`: The name of the controller to created. It could be a function. | ||
* `controllerAs` : The name of the variable on the scope the controller is assigned to - (optional). | ||
* `controllerAs` : The name of the variable on the scope instance of the controller is assigned to - (optional). | ||
* `templateUrl`: The URL of the HTML template to use for the modal. | ||
@@ -143,2 +153,3 @@ * `template`: If `templateUrl` is not specified, you can specify `template` as raw | ||
* `appendElement`: The custom angular element to append the modal to instead of default `body` element. | ||
* `scope`: Optional. If provided, the modal controller will use a new scope as a child of `scope` (created by calling `scope.$new()`) rather than a new scope created as a child of `$rootScope`. | ||
@@ -154,3 +165,4 @@ #### The Modal Object | ||
* `modal.controller` - The new controller created for the modal. | ||
* `modal.close` - A promise which is resolved when the modal is closed. | ||
* `modal.close` - A promise which is resolved when the modal `close` function is called. | ||
* `modal.closed` - A promise which is resolved once the modal has finished animating out of the DOM. | ||
@@ -161,4 +173,29 @@ #### The Modal Controller | ||
called `close`. Call this function with any parameter (the result). This result parameter is | ||
then passed as the parameter of the `close` promise used by the caller. | ||
then passed as the parameter of the `close` and `closed` promises used by the caller. | ||
### Animation | ||
`ModalService` cooperates with Angular's `$animate` service to allow easy implementation of | ||
custom animation. Specifically, `showModal` will trigger the `ng-enter` hook, and calling | ||
`close` will trigger the `ng-leave` hook. For example, if the `ngAnimate` module is | ||
installed, the following CSS rules will add fade in/fade out animations to a modal with the | ||
class `modal`: | ||
```css | ||
.modal.ng-enter { | ||
transition: opacity .5s ease-out; | ||
opacity: 0; | ||
} | ||
.modal.ng-enter.ng-enter-active { | ||
opacity: 1; | ||
} | ||
.modal.ng-leave { | ||
transition: opacity .5s ease-out; | ||
opacity: 1; | ||
} | ||
.modal.ng-leave.ng-leave-active { | ||
opacity: 0; | ||
} | ||
``` | ||
### Error Handing | ||
@@ -283,2 +320,2 @@ | ||
* [jonasnas](https://github.com/jonasnas) - Fixing template cache logic. | ||
* [maxdow](https://github.com/maxdow) - Added support for controller inlining. | ||
* [maxdow](https://github.com/maxdow) - Added support for controller inlining. |
@@ -5,9 +5,4 @@ var app = angular.module('sampleapp'); | ||
$scope.display = true; | ||
$scope.close = close; | ||
$scope.close = function() { | ||
$scope.display = false; | ||
close(); | ||
}; | ||
}]); | ||
}]); |
// Build our app module, with a dependency on the angular modal service. | ||
var app = angular.module('sampleapp', ['angularModalService']); | ||
var app = angular.module('sampleapp', ['angularModalService', 'ngAnimate']); | ||
app.controller('SampleController', ['$scope', 'ModalService', function($scope, ModalService) { | ||
$scope.yesNoResult = null; | ||
@@ -54,2 +54,2 @@ $scope.complexResult = null; | ||
}]); | ||
}]); |
@@ -13,4 +13,4 @@ // angularModalService.js | ||
module.factory('ModalService', ['$document', '$compile', '$controller', '$http', '$rootScope', '$q', '$templateCache', | ||
function($document, $compile, $controller, $http, $rootScope, $q, $templateCache) { | ||
module.factory('ModalService', ['$animate', '$document', '$compile', '$controller', '$http', '$rootScope', '$q', '$templateRequest', '$timeout', | ||
function($animate, $document, $compile, $controller, $http, $rootScope, $q, $templateRequest, $timeout) { | ||
@@ -29,9 +29,8 @@ // Get the body of the document, we'll add the modal to this. | ||
var deferred = $q.defer(); | ||
if(template) { | ||
if (template) { | ||
deferred.resolve(template); | ||
} else if(templateUrl) { | ||
// Get the template, using the $templateCache. | ||
$http.get(templateUrl, {cache: $templateCache}) | ||
.then(function(result) { | ||
deferred.resolve(result.data); | ||
} else if (templateUrl) { | ||
$templateRequest(templateUrl, true) | ||
.then(function(template) { | ||
deferred.resolve(template); | ||
}, function(error) { | ||
@@ -46,2 +45,13 @@ deferred.reject(error); | ||
// Adds an element to the DOM as the last child of its container | ||
// like append, but uses $animate to handle animations. Returns a | ||
// promise that is resolved once all animation is complete. | ||
var appendChild = function(parent, child) { | ||
var children = parent.children(); | ||
if (children.length > 0) { | ||
return $animate.enter(child, parent, children[children.length - 1]); | ||
} | ||
return $animate.enter(child, parent); | ||
}; | ||
self.showModal = function(options) { | ||
@@ -54,3 +64,3 @@ | ||
var controllerName = options.controller; | ||
if(!controllerName) { | ||
if (!controllerName) { | ||
deferred.reject("No controller has been specified."); | ||
@@ -65,3 +75,3 @@ return deferred.promise; | ||
// Create a new scope for the modal. | ||
var modalScope = $rootScope.$new(); | ||
var modalScope = (options.scope || $rootScope).$new(); | ||
@@ -75,24 +85,31 @@ // Create the inputs object to the controller - this will include | ||
var closeDeferred = $q.defer(); | ||
var closedDeferred = $q.defer(); | ||
var inputs = { | ||
$scope: modalScope, | ||
close: function(result, delay) { | ||
if(delay === undefined || delay === null) delay = 0; | ||
window.setTimeout(function() { | ||
if (delay === undefined || delay === null) delay = 0; | ||
$timeout(function() { | ||
// Resolve the 'close' promise. | ||
closeDeferred.resolve(result); | ||
// We can now clean up the scope and remove the element from the DOM. | ||
modalScope.$destroy(); | ||
modalElement.remove(); | ||
// Let angular remove the element and wait for animations to finish. | ||
$animate.leave(modalElement) | ||
.then(function () { | ||
// Resolve the 'closed' promise. | ||
closedDeferred.resolve(result); | ||
// Unless we null out all of these objects we seem to suffer | ||
// from memory leaks, if anyone can explain why then I'd | ||
// be very interested to know. | ||
inputs.close = null; | ||
deferred = null; | ||
closeDeferred = null; | ||
modal = null; | ||
inputs = null; | ||
modalElement = null; | ||
modalScope = null; | ||
// We can now clean up the scope | ||
modalScope.$destroy(); | ||
// Unless we null out all of these objects we seem to suffer | ||
// from memory leaks, if anyone can explain why then I'd | ||
// be very interested to know. | ||
inputs.close = null; | ||
deferred = null; | ||
closeDeferred = null; | ||
modal = null; | ||
inputs = null; | ||
modalElement = null; | ||
modalScope = null; | ||
}); | ||
}, delay); | ||
@@ -103,3 +120,3 @@ } | ||
// If we have provided any inputs, pass them to the controller. | ||
if(options.inputs) angular.extend(inputs, options.inputs); | ||
if (options.inputs) angular.extend(inputs, options.inputs); | ||
@@ -113,14 +130,16 @@ // Compile then link the template element, building the actual element. | ||
// Create the controller, explicitly specifying the scope to use. | ||
var modalController = $controller(options.controller, inputs); | ||
var controllerObjBefore = modalScope[options.controllerAs]; | ||
var modalController = $controller(options.controller, inputs, false, options.controllerAs); | ||
if(options.controllerAs){ | ||
modalScope[options.controllerAs] = modalController ; | ||
if (options.controllerAs && controllerObjBefore) { | ||
angular.extend(modalController, controllerObjBefore); | ||
} | ||
// Finally, append the modal to the dom. | ||
if (options.appendElement) { | ||
// append to custom append element | ||
options.appendElement.append(modalElement); | ||
appendChild(options.appendElement, modalElement); | ||
} else { | ||
// append to body when no custom append element is specified | ||
body.append(modalElement); | ||
appendChild(body, modalElement); | ||
} | ||
@@ -133,3 +152,4 @@ | ||
element: modalElement, | ||
close: closeDeferred.promise | ||
close: closeDeferred.promise, | ||
closed: closedDeferred.promise | ||
}; | ||
@@ -136,0 +156,0 @@ |
@@ -17,3 +17,7 @@ describe('controller', function() { | ||
.controller('ControllerAsController', function() { | ||
this.character = "Fry"; | ||
var vm = this; | ||
vm.character = "Fry"; | ||
vm.checkValidity = function() { | ||
return vm.ExampleForm.$valid; | ||
} | ||
}) | ||
@@ -31,2 +35,5 @@ .controller('ElementController', function($scope, $element) { | ||
$httpBackend.when('GET', 'some/controllertemplate.html').respond("<div id='controllertemplate'>controller template</div>"); | ||
$httpBackend.when('GET', 'some/formtemplate.html').respond( | ||
"<form name='formCtrl.ExampleForm'><input type='text' name='exampleInput'></form>" | ||
); | ||
}); | ||
@@ -196,2 +203,19 @@ }); | ||
}); | ||
it('should correct process form with controllerAs.form syntax', function() { | ||
$httpBackend.expectGET('some/formtemplate.html'); | ||
ModalService.showModal({ | ||
controller: 'ControllerAsController', | ||
controllerAs: 'formCtrl', | ||
templateUrl: 'some/formtemplate.html' | ||
}).then(function(modal) { | ||
expect(modal.scope.formCtrl.ExampleForm).not.toBeUndefined(); | ||
expect(modal.scope.formCtrl.checkValidity()).toBe(true); | ||
}); | ||
$httpBackend.flush(); | ||
}); | ||
}); |
@@ -27,3 +27,3 @@ describe('dom', function() { | ||
}); | ||
it('should add the template html to the dom', function() { | ||
@@ -37,3 +37,3 @@ | ||
}).then(function(modal) { | ||
// We should be able to find the element that has been created in the dom. | ||
@@ -45,3 +45,3 @@ expect(document.getElementById('template1')).not.toBeNull(); | ||
$httpBackend.flush(); | ||
}); | ||
@@ -99,3 +99,3 @@ | ||
}); | ||
it('should remove the template html from the dom when the controller closes the modal', function() { | ||
@@ -109,7 +109,7 @@ | ||
}).then(function(modal) { | ||
// We should be able to find the element that has been created in the dom. | ||
expect(document.getElementById('template2')).not.toBeNull(); | ||
modal.close.then(function(result) { | ||
modal.closed.then(function(result) { | ||
expect(document.getElementById('template2')).toBeNull(); | ||
@@ -123,5 +123,5 @@ }); | ||
$timeout.flush(); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
2803662
47
48219
311
0
4