Comparing version 0.4.0 to 0.5.0
{ | ||
"name": "ngDialog", | ||
"version": "0.4.0", | ||
"homepage": "https://github.com/likeastore/ngDialog", | ||
@@ -36,7 +35,7 @@ "description": "Modal dialogs and popups provider for Angular.js applications", | ||
"dependencies": { | ||
"angular": "~1.3.x" | ||
"angular": "^1.4.x" | ||
}, | ||
"devDependencies": { | ||
"angular-mocks": "~1.3.14" | ||
"angular-mocks": "^1.4.x" | ||
} | ||
} |
@@ -38,3 +38,3 @@ # 0.4.0 | ||
- [x] get rid of `module` variable in source code | ||
- [x] get rid of `window` dependency in flavor of `$window` | ||
- [x] get rid of `window` dependency in favor of `$window` | ||
@@ -41,0 +41,0 @@ # 0.3.6 |
@@ -10,3 +10,7 @@ /* | ||
// CommonJS | ||
module.exports = factory(require('angular')); | ||
if (typeof angular === 'undefined') { | ||
module.exports = factory(require('angular')); | ||
} else { | ||
module.exports = factory(angular); | ||
} | ||
} else if (typeof define === 'function' && define.amd) { | ||
@@ -30,3 +34,4 @@ // AMD | ||
var focusableElementSelector = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]'; | ||
var forceBodyReload = false; | ||
var disabledAnimationClass = 'ngdialog-disabled-animation'; | ||
var forceElementsReload = { html: false, body: false }; | ||
var scopes = {}; | ||
@@ -39,2 +44,3 @@ var openIdStack = []; | ||
className: 'ngdialog-theme-default', | ||
disableAnimation: false, | ||
plain: false, | ||
@@ -59,4 +65,8 @@ showClose: true, | ||
this.setForceHtmlReload = function (_useIt) { | ||
forceElementsReload.html = _useIt || false; | ||
}; | ||
this.setForceBodyReload = function (_useIt) { | ||
forceBodyReload = _useIt || false; | ||
forceElementsReload.body = _useIt || false; | ||
}; | ||
@@ -72,9 +82,17 @@ | ||
function ($document, $templateCache, $compile, $q, $http, $rootScope, $timeout, $window, $controller, $injector) { | ||
var $body = $document.find('body'); | ||
if (forceBodyReload) { | ||
$rootScope.$on('$locationChangeSuccess', function () { | ||
$body = $document.find('body'); | ||
}); | ||
} | ||
var $elements = []; | ||
angular.forEach( | ||
['html', 'body'], | ||
function(elementName) { | ||
$elements[elementName] = $document.find(elementName); | ||
if (forceElementsReload[elementName]) { | ||
var eventName = privateMethods.getRouterLocationEventName(); | ||
$rootScope.$on(eventName, function () { | ||
$elements[elementName] = $document.find(elementName); | ||
}); | ||
} | ||
} | ||
); | ||
var privateMethods = { | ||
@@ -94,3 +112,3 @@ onDocumentKeydown: function (event) { | ||
// Catch rogue changes (eg. after unfocusing everything by clicking a non-focusable element) | ||
$body.on('keydown', privateMethods.onTrapFocusKeydown); | ||
$elements.body.on('keydown', privateMethods.onTrapFocusKeydown); | ||
} | ||
@@ -101,3 +119,3 @@ }, | ||
$dialog.off('keydown', privateMethods.onTrapFocusKeydown); | ||
$body.off('keydown', privateMethods.onTrapFocusKeydown); | ||
$elements.body.off('keydown', privateMethods.onTrapFocusKeydown); | ||
}, | ||
@@ -113,13 +131,13 @@ | ||
setBodyPadding: function (width) { | ||
var originalBodyPadding = parseInt(($body.css('padding-right') || 0), 10); | ||
$body.css('padding-right', (originalBodyPadding + width) + 'px'); | ||
$body.data('ng-dialog-original-padding', originalBodyPadding); | ||
var originalBodyPadding = parseInt(($elements.body.css('padding-right') || 0), 10); | ||
$elements.body.css('padding-right', (originalBodyPadding + width) + 'px'); | ||
$elements.body.data('ng-dialog-original-padding', originalBodyPadding); | ||
}, | ||
resetBodyPadding: function () { | ||
var originalBodyPadding = $body.data('ng-dialog-original-padding'); | ||
var originalBodyPadding = $elements.body.data('ng-dialog-original-padding'); | ||
if (originalBodyPadding) { | ||
$body.css('padding-right', originalBodyPadding + 'px'); | ||
$elements.body.css('padding-right', originalBodyPadding + 'px'); | ||
} else { | ||
$body.css('padding-right', ''); | ||
$elements.body.css('padding-right', ''); | ||
} | ||
@@ -129,2 +147,3 @@ }, | ||
performCloseDialog: function ($dialog, value) { | ||
var options = $dialog.data('$ngDialogOptions'); | ||
var id = $dialog.attr('id'); | ||
@@ -148,3 +167,3 @@ var scope = scopes[id]; | ||
if (dialogsCount === 1) { | ||
$body.unbind('keydown'); | ||
$elements.body.unbind('keydown', privateMethods.onDocumentKeydown); | ||
} | ||
@@ -161,22 +180,12 @@ | ||
$rootScope.$broadcast('ngDialog.closing', $dialog); | ||
$rootScope.$broadcast('ngDialog.closing', $dialog, value); | ||
dialogsCount = dialogsCount < 0 ? 0 : dialogsCount; | ||
if (animationEndSupport) { | ||
if (animationEndSupport && !options.disableAnimation) { | ||
scope.$destroy(); | ||
$dialog.unbind(animationEndEvent).bind(animationEndEvent, function () { | ||
$dialog.remove(); | ||
if (dialogsCount === 0) { | ||
$body.removeClass('ngdialog-open'); | ||
privateMethods.resetBodyPadding(); | ||
} | ||
$rootScope.$broadcast('ngDialog.closed', $dialog); | ||
privateMethods.closeDialogElement($dialog, value); | ||
}).addClass('ngdialog-closing'); | ||
} else { | ||
scope.$destroy(); | ||
$dialog.remove(); | ||
if (dialogsCount === 0) { | ||
$body.removeClass('ngdialog-open'); | ||
privateMethods.resetBodyPadding(); | ||
} | ||
$rootScope.$broadcast('ngDialog.closed', $dialog); | ||
privateMethods.closeDialogElement($dialog, value); | ||
} | ||
@@ -197,3 +206,3 @@ if (defers[id]) { | ||
if (!openIdStack.length) { | ||
$body.unbind('keydown', privateMethods.onDocumentKeydown); | ||
$elements.body.unbind('keydown', privateMethods.onDocumentKeydown); | ||
keydownIsBound = false; | ||
@@ -203,2 +212,12 @@ } | ||
closeDialogElement: function($dialog, value) { | ||
$dialog.remove(); | ||
if (dialogsCount === 0) { | ||
$elements.html.removeClass('ngdialog-open'); | ||
$elements.body.removeClass('ngdialog-open'); | ||
privateMethods.resetBodyPadding(); | ||
} | ||
$rootScope.$broadcast('ngDialog.closed', $dialog, value); | ||
}, | ||
closeDialog: function ($dialog, value) { | ||
@@ -327,5 +346,22 @@ var preCloseCallback = $dialog.data('$ngDialogPreCloseCallback'); | ||
return privateMethods.filterVisibleElements(rawElements); | ||
// Ignore untabbable elements, ie. those with tabindex = -1 | ||
var tabbableElements = privateMethods.filterTabbableElements(rawElements); | ||
return privateMethods.filterVisibleElements(tabbableElements); | ||
}, | ||
filterTabbableElements: function (els) { | ||
var tabbableFocusableElements = []; | ||
for (var i = 0; i < els.length; i++) { | ||
var el = els[i]; | ||
if ($el(el).attr('tabindex') !== '-1') { | ||
tabbableFocusableElements.push(el); | ||
} | ||
} | ||
return tabbableFocusableElements; | ||
}, | ||
filterVisibleElements: function (els) { | ||
@@ -408,2 +444,19 @@ var visibleFocusableElements = []; | ||
} | ||
}, | ||
detectUIRouter: function() { | ||
//Detect if ui-router module is installed if not return false | ||
try { | ||
angular.module("ui.router"); | ||
return true; | ||
} catch(err) { | ||
return false; | ||
} | ||
}, | ||
getRouterLocationEventName: function() { | ||
if(privateMethods.detectUIRouter()) { | ||
return '$stateChangeSuccess'; | ||
} | ||
return '$locationChangeSuccess'; | ||
} | ||
@@ -422,2 +475,3 @@ }; | ||
* - className {String} - dialog theme class | ||
* - disableAnimation {Boolean} - set to true to disable animation | ||
* - showClose {Boolean} - show close button, default true | ||
@@ -460,4 +514,2 @@ * - closeByEscape {Boolean} - default true | ||
$templateCache.put(options.template || options.templateUrl, template); | ||
if (options.showClose) { | ||
@@ -474,7 +526,11 @@ template += '<div class="ngdialog-close"></div>'; | ||
scope.ngDialogId = dialogID; | ||
if (options.data && angular.isString(options.data)) { | ||
var firstLetter = options.data.replace(/^\s*/, '')[0]; | ||
scope.ngDialogData = (firstLetter === '{' || firstLetter === '[') ? angular.fromJson(options.data) : options.data; | ||
scope.ngDialogData.ngDialogId = dialogID; | ||
} else if (options.data && angular.isObject(options.data)) { | ||
scope.ngDialogData = options.data; | ||
scope.ngDialogData.ngDialogId = dialogID; | ||
} | ||
@@ -484,8 +540,9 @@ | ||
var ctrl = options.controller; | ||
var label; | ||
if (options.controllerAs && angular.isString(options.controllerAs)) { | ||
ctrl += ' as ' + options.controllerAs; | ||
label = options.controllerAs; | ||
} | ||
var controllerInstance = $controller(ctrl, angular.extend( | ||
var controllerInstance = $controller(options.controller, angular.extend( | ||
locals, | ||
@@ -495,4 +552,6 @@ { | ||
$element: $dialog | ||
} | ||
)); | ||
}), | ||
null, | ||
label | ||
); | ||
$dialog.data('$ngDialogControllerController', controllerInstance); | ||
@@ -505,6 +564,10 @@ } | ||
if (options.disableAnimation) { | ||
$dialog.addClass(disabledAnimationClass); | ||
} | ||
if (options.appendTo && angular.isString(options.appendTo)) { | ||
$dialogParent = angular.element(document.querySelector(options.appendTo)); | ||
} else { | ||
$dialogParent = $body; | ||
$dialogParent = $elements.body; | ||
} | ||
@@ -545,5 +608,6 @@ | ||
$compile($dialog)(scope); | ||
var widthDiffs = $window.innerWidth - $body.prop('clientWidth'); | ||
$body.addClass('ngdialog-open'); | ||
var scrollBarWidth = widthDiffs - ($window.innerWidth - $body.prop('clientWidth')); | ||
var widthDiffs = $window.innerWidth - $elements.body.prop('clientWidth'); | ||
$elements.html.addClass('ngdialog-open'); | ||
$elements.body.addClass('ngdialog-open'); | ||
var scrollBarWidth = widthDiffs - ($window.innerWidth - $elements.body.prop('clientWidth')); | ||
if (scrollBarWidth > 0) { | ||
@@ -568,3 +632,3 @@ privateMethods.setBodyPadding(scrollBarWidth); | ||
if (!keydownIsBound) { | ||
$body.bind('keydown', privateMethods.onDocumentKeydown); | ||
$elements.body.bind('keydown', privateMethods.onDocumentKeydown); | ||
keydownIsBound = true; | ||
@@ -574,3 +638,4 @@ } | ||
if (options.closeByNavigation) { | ||
$rootScope.$on('$locationChangeSuccess', function () { | ||
var eventName = privateMethods.getRouterLocationEventName(); | ||
$rootScope.$on(eventName, function () { | ||
privateMethods.closeDialog($dialog); | ||
@@ -614,3 +679,5 @@ }); | ||
function loadTemplateUrl (tmpl, config) { | ||
$rootScope.$broadcast('ngDialog.templateLoading', tmpl); | ||
return $http.get(tmpl, (config || {})).then(function(res) { | ||
$rootScope.$broadcast('ngDialog.templateLoaded', tmpl); | ||
return res.data || ''; | ||
@@ -633,3 +700,3 @@ }); | ||
return $templateCache.get(tmpl) || loadTemplateUrl(tmpl, {cache: true}); | ||
return loadTemplateUrl(tmpl, {cache: $templateCache}); | ||
} | ||
@@ -702,2 +769,4 @@ }, | ||
} | ||
} else { | ||
publicMethods.closeAll(value); | ||
} | ||
@@ -719,2 +788,6 @@ } | ||
getOpenDialogs: function() { | ||
return openIdStack; | ||
}, | ||
getDefaults: function () { | ||
@@ -749,2 +822,3 @@ return defaults; | ||
controllerAs: attrs.ngDialogControllerAs, | ||
bindToController: attrs.ngDialogBindToController, | ||
scope: ngDialogScope, | ||
@@ -755,2 +829,3 @@ data: attrs.ngDialogData, | ||
closeByEscape: attrs.ngDialogCloseByEscape === 'false' ? false : (attrs.ngDialogCloseByEscape === 'true' ? true : defaults.closeByEscape), | ||
overlay: attrs.ngDialogOverlay === 'false' ? false : (attrs.ngDialogOverlay === 'true' ? true : defaults.overlay), | ||
preCloseCallback: attrs.ngDialogPreCloseCallback || defaults.preCloseCallback | ||
@@ -757,0 +832,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
/*! ng-dialog - v0.4.0 (https://github.com/likeastore/ngDialog) */ | ||
!function(a,b){"undefined"!=typeof module&&module.exports?module.exports=b(require("angular")):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(this,function(a){"use strict";var b=a.module("ngDialog",[]),c=a.element,d=a.isDefined,e=(document.body||document.documentElement).style,f=d(e.animation)||d(e.WebkitAnimation)||d(e.MozAnimation)||d(e.MsAnimation)||d(e.OAnimation),g="animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",h="a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]",i=!1,j={},k=[],l=!1;return b.provider("ngDialog",function(){var b=this.defaults={className:"ngdialog-theme-default",plain:!1,showClose:!0,closeByDocument:!0,closeByEscape:!0,closeByNavigation:!1,appendTo:!1,preCloseCallback:!1,overlay:!0,cache:!0,trapFocus:!0,preserveFocus:!0,ariaAuto:!0,ariaRole:null,ariaLabelledById:null,ariaLabelledBySelector:null,ariaDescribedById:null,ariaDescribedBySelector:null};this.setForceBodyReload=function(a){i=a||!1},this.setDefaults=function(c){a.extend(b,c)};var d,e=0,m=0,n={};this.$get=["$document","$templateCache","$compile","$q","$http","$rootScope","$timeout","$window","$controller","$injector",function(o,p,q,r,s,t,u,v,w,x){var y=o.find("body");i&&t.$on("$locationChangeSuccess",function(){y=o.find("body")});var z={onDocumentKeydown:function(a){27===a.keyCode&&A.close("$escape")},activate:function(a){var b=a.data("$ngDialogOptions");b.trapFocus&&(a.on("keydown",z.onTrapFocusKeydown),y.on("keydown",z.onTrapFocusKeydown))},deactivate:function(a){a.off("keydown",z.onTrapFocusKeydown),y.off("keydown",z.onTrapFocusKeydown)},deactivateAll:function(){a.forEach(function(b){var c=a.element(b);z.deactivate(c)})},setBodyPadding:function(a){var b=parseInt(y.css("padding-right")||0,10);y.css("padding-right",b+a+"px"),y.data("ng-dialog-original-padding",b)},resetBodyPadding:function(){var a=y.data("ng-dialog-original-padding");a?y.css("padding-right",a+"px"):y.css("padding-right","")},performCloseDialog:function(a,b){var c=a.attr("id"),e=j[c];if(e){if("undefined"!=typeof v.Hammer){var h=e.hammerTime;h.off("tap",d),h.destroy&&h.destroy(),delete e.hammerTime}else a.unbind("click");1===m&&y.unbind("keydown"),a.hasClass("ngdialog-closing")||(m-=1);var i=a.data("$ngDialogPreviousFocus");i&&i.focus(),t.$broadcast("ngDialog.closing",a),m=0>m?0:m,f?(e.$destroy(),a.unbind(g).bind(g,function(){a.remove(),0===m&&(y.removeClass("ngdialog-open"),z.resetBodyPadding()),t.$broadcast("ngDialog.closed",a)}).addClass("ngdialog-closing")):(e.$destroy(),a.remove(),0===m&&(y.removeClass("ngdialog-open"),z.resetBodyPadding()),t.$broadcast("ngDialog.closed",a)),n[c]&&(n[c].resolve({id:c,value:b,$dialog:a,remainingDialogs:m}),delete n[c]),j[c]&&delete j[c],k.splice(k.indexOf(c),1),k.length||(y.unbind("keydown",z.onDocumentKeydown),l=!1)}},closeDialog:function(b,c){var d=b.data("$ngDialogPreCloseCallback");if(d&&a.isFunction(d)){var e=d.call(b,c);a.isObject(e)?e.closePromise?e.closePromise.then(function(){z.performCloseDialog(b,c)}):e.then(function(){z.performCloseDialog(b,c)},function(){}):e!==!1&&z.performCloseDialog(b,c)}else z.performCloseDialog(b,c)},onTrapFocusKeydown:function(b){var c,d=a.element(b.currentTarget);if(d.hasClass("ngdialog"))c=d;else if(c=z.getActiveDialog(),null===c)return;var e=9===b.keyCode,f=b.shiftKey===!0;e&&z.handleTab(c,b,f)},handleTab:function(a,b,c){var d=z.getFocusableElements(a);if(0===d.length)return document.activeElement&&document.activeElement.blur(),void 0;var e=document.activeElement,f=Array.prototype.indexOf.call(d,e),g=-1===f,h=0===f,i=f===d.length-1,j=!1;c?(g||h)&&(d[d.length-1].focus(),j=!0):(g||i)&&(d[0].focus(),j=!0),j&&(b.preventDefault(),b.stopPropagation())},autoFocus:function(a){var b=a[0],d=b.querySelector("*[autofocus]");if(null===d||(d.focus(),document.activeElement!==d)){var e=z.getFocusableElements(a);if(e.length>0)return e[0].focus(),void 0;var f=z.filterVisibleElements(b.querySelectorAll("h1,h2,h3,h4,h5,h6,p,span"));if(f.length>0){var g=f[0];c(g).attr("tabindex","-1").css("outline","0"),g.focus()}}},getFocusableElements:function(a){var b=a[0],c=b.querySelectorAll(h);return z.filterVisibleElements(c)},filterVisibleElements:function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];(d.offsetWidth>0||d.offsetHeight>0)&&b.push(d)}return b},getActiveDialog:function(){var a=document.querySelectorAll(".ngdialog");return 0===a.length?null:c(a[a.length-1])},applyAriaAttributes:function(a,b){if(b.ariaAuto){if(!b.ariaRole){var c=z.getFocusableElements(a).length>0?"dialog":"alertdialog";b.ariaRole=c}b.ariaLabelledBySelector||(b.ariaLabelledBySelector="h1,h2,h3,h4,h5,h6"),b.ariaDescribedBySelector||(b.ariaDescribedBySelector="article,section,p")}b.ariaRole&&a.attr("role",b.ariaRole),z.applyAriaAttribute(a,"aria-labelledby",b.ariaLabelledById,b.ariaLabelledBySelector),z.applyAriaAttribute(a,"aria-describedby",b.ariaDescribedById,b.ariaDescribedBySelector)},applyAriaAttribute:function(a,b,d,e){if(d&&a.attr(b,d),e){var f=a.attr("id"),g=a[0].querySelector(e);if(!g)return;var h=f+"-"+b;return c(g).attr("id",h),a.attr(b,h),h}}},A={open:function(f){function g(a,b){return s.get(a,b||{}).then(function(a){return a.data||""})}function h(b){return b?a.isString(b)&&i.plain?b:"boolean"!=typeof i.cache||i.cache?p.get(b)||g(b,{cache:!0}):g(b,{cache:!1}):"Empty template"}var i=a.copy(b),o=++e,B="ngdialog"+o;k.push(B),f=f||{},a.extend(i,f);var C;n[B]=C=r.defer();var D;j[B]=D=a.isObject(i.scope)?i.scope.$new():t.$new();var E,F,G=a.extend({},i.resolve);return a.forEach(G,function(b,c){G[c]=a.isString(b)?x.get(b):x.invoke(b,null,null,c)}),r.all({template:h(i.template||i.templateUrl),locals:r.all(G)}).then(function(b){var e=b.template,f=b.locals;if(p.put(i.template||i.templateUrl,e),i.showClose&&(e+='<div class="ngdialog-close"></div>'),E=c('<div id="ngdialog'+o+'" class="ngdialog"></div>'),E.html(i.overlay?'<div class="ngdialog-overlay"></div><div class="ngdialog-content" role="document">'+e+"</div>":'<div class="ngdialog-content" role="document">'+e+"</div>"),E.data("$ngDialogOptions",i),i.data&&a.isString(i.data)){var g=i.data.replace(/^\s*/,"")[0];D.ngDialogData="{"===g||"["===g?a.fromJson(i.data):i.data}else i.data&&a.isObject(i.data)&&(D.ngDialogData=i.data);if(i.controller&&(a.isString(i.controller)||a.isArray(i.controller)||a.isFunction(i.controller))){var h=i.controller;i.controllerAs&&a.isString(i.controllerAs)&&(h+=" as "+i.controllerAs);var j=w(h,a.extend(f,{$scope:D,$element:E}));E.data("$ngDialogControllerController",j)}if(i.className&&E.addClass(i.className),F=i.appendTo&&a.isString(i.appendTo)?a.element(document.querySelector(i.appendTo)):y,z.applyAriaAttributes(E,i),i.preCloseCallback){var k;a.isFunction(i.preCloseCallback)?k=i.preCloseCallback:a.isString(i.preCloseCallback)&&D&&(a.isFunction(D[i.preCloseCallback])?k=D[i.preCloseCallback]:D.$parent&&a.isFunction(D.$parent[i.preCloseCallback])?k=D.$parent[i.preCloseCallback]:t&&a.isFunction(t[i.preCloseCallback])&&(k=t[i.preCloseCallback])),k&&E.data("$ngDialogPreCloseCallback",k)}if(D.closeThisDialog=function(a){z.closeDialog(E,a)},u(function(){var a=document.querySelectorAll(".ngdialog");z.deactivateAll(a),q(E)(D);var b=v.innerWidth-y.prop("clientWidth");y.addClass("ngdialog-open");var c=b-(v.innerWidth-y.prop("clientWidth"));c>0&&z.setBodyPadding(c),F.append(E),z.activate(E),i.trapFocus&&z.autoFocus(E),i.name?t.$broadcast("ngDialog.opened",{dialog:E,name:i.name}):t.$broadcast("ngDialog.opened",E)}),l||(y.bind("keydown",z.onDocumentKeydown),l=!0),i.closeByNavigation&&t.$on("$locationChangeSuccess",function(){z.closeDialog(E)}),i.preserveFocus&&E.data("$ngDialogPreviousFocus",document.activeElement),d=function(a){var b=i.closeByDocument?c(a.target).hasClass("ngdialog-overlay"):!1,d=c(a.target).hasClass("ngdialog-close");(b||d)&&A.close(E.attr("id"),d?"$closeButton":"$document")},"undefined"!=typeof v.Hammer){var n=D.hammerTime=v.Hammer(E[0]);n.on("tap",d)}else E.bind("click",d);return m+=1,A}),{id:B,closePromise:C.promise,close:function(a){z.closeDialog(E,a)}}},openConfirm:function(b){var d=r.defer(),e={closeByEscape:!1,closeByDocument:!1};a.extend(e,b),e.scope=a.isObject(e.scope)?e.scope.$new():t.$new(),e.scope.confirm=function(a){d.resolve(a);var b=c(document.getElementById(f.id));z.performCloseDialog(b,a)};var f=A.open(e);return f.closePromise.then(function(a){return a?d.reject(a.value):d.reject()}),d.promise},isOpen:function(a){var b=c(document.getElementById(a));return b.length>0},close:function(a,b){var d=c(document.getElementById(a));if(d.length)z.closeDialog(d,b);else if("$escape"===a){var e=k[k.length-1];d=c(document.getElementById(e)),d.data("$ngDialogOptions").closeByEscape&&z.closeDialog(d,b)}return A},closeAll:function(a){for(var b=document.querySelectorAll(".ngdialog"),d=b.length-1;d>=0;d--){var e=b[d];z.closeDialog(c(e),a)}},getDefaults:function(){return b}};return A}]}),b.directive("ngDialog",["ngDialog",function(b){return{restrict:"A",scope:{ngDialogScope:"="},link:function(c,d,e){d.on("click",function(d){d.preventDefault();var f=a.isDefined(c.ngDialogScope)?c.ngDialogScope:"noScope";a.isDefined(e.ngDialogClosePrevious)&&b.close(e.ngDialogClosePrevious);var g=b.getDefaults();b.open({template:e.ngDialog,className:e.ngDialogClass||g.className,controller:e.ngDialogController,controllerAs:e.ngDialogControllerAs,scope:f,data:e.ngDialogData,showClose:"false"===e.ngDialogShowClose?!1:"true"===e.ngDialogShowClose?!0:g.showClose,closeByDocument:"false"===e.ngDialogCloseByDocument?!1:"true"===e.ngDialogCloseByDocument?!0:g.closeByDocument,closeByEscape:"false"===e.ngDialogCloseByEscape?!1:"true"===e.ngDialogCloseByEscape?!0:g.closeByEscape,preCloseCallback:e.ngDialogPreCloseCallback||g.preCloseCallback})})}}}]),b}); | ||
/*! ng-dialog - v0.5.0 (https://github.com/likeastore/ngDialog) */ | ||
!function(a,b){"undefined"!=typeof module&&module.exports?module.exports="undefined"==typeof angular?b(require("angular")):b(angular):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(this,function(a){"use strict";var b=a.module("ngDialog",[]),c=a.element,d=a.isDefined,e=(document.body||document.documentElement).style,f=d(e.animation)||d(e.WebkitAnimation)||d(e.MozAnimation)||d(e.MsAnimation)||d(e.OAnimation),g="animationend webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend",h="a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]",i="ngdialog-disabled-animation",j={html:!1,body:!1},k={},l=[],m=!1;return b.provider("ngDialog",function(){var b=this.defaults={className:"ngdialog-theme-default",disableAnimation:!1,plain:!1,showClose:!0,closeByDocument:!0,closeByEscape:!0,closeByNavigation:!1,appendTo:!1,preCloseCallback:!1,overlay:!0,cache:!0,trapFocus:!0,preserveFocus:!0,ariaAuto:!0,ariaRole:null,ariaLabelledById:null,ariaLabelledBySelector:null,ariaDescribedById:null,ariaDescribedBySelector:null};this.setForceHtmlReload=function(a){j.html=a||!1},this.setForceBodyReload=function(a){j.body=a||!1},this.setDefaults=function(c){a.extend(b,c)};var d,e=0,n=0,o={};this.$get=["$document","$templateCache","$compile","$q","$http","$rootScope","$timeout","$window","$controller","$injector",function(p,q,r,s,t,u,v,w,x,y){var z=[];a.forEach(["html","body"],function(a){if(z[a]=p.find(a),j[a]){var b=A.getRouterLocationEventName();u.$on(b,function(){z[a]=p.find(a)})}});var A={onDocumentKeydown:function(a){27===a.keyCode&&B.close("$escape")},activate:function(a){var b=a.data("$ngDialogOptions");b.trapFocus&&(a.on("keydown",A.onTrapFocusKeydown),z.body.on("keydown",A.onTrapFocusKeydown))},deactivate:function(a){a.off("keydown",A.onTrapFocusKeydown),z.body.off("keydown",A.onTrapFocusKeydown)},deactivateAll:function(){a.forEach(function(b){var c=a.element(b);A.deactivate(c)})},setBodyPadding:function(a){var b=parseInt(z.body.css("padding-right")||0,10);z.body.css("padding-right",b+a+"px"),z.body.data("ng-dialog-original-padding",b)},resetBodyPadding:function(){var a=z.body.data("ng-dialog-original-padding");a?z.body.css("padding-right",a+"px"):z.body.css("padding-right","")},performCloseDialog:function(a,b){var c=a.data("$ngDialogOptions"),e=a.attr("id"),h=k[e];if(h){if("undefined"!=typeof w.Hammer){var i=h.hammerTime;i.off("tap",d),i.destroy&&i.destroy(),delete h.hammerTime}else a.unbind("click");1===n&&z.body.unbind("keydown",A.onDocumentKeydown),a.hasClass("ngdialog-closing")||(n-=1);var j=a.data("$ngDialogPreviousFocus");j&&j.focus(),u.$broadcast("ngDialog.closing",a,b),n=0>n?0:n,f&&!c.disableAnimation?(h.$destroy(),a.unbind(g).bind(g,function(){A.closeDialogElement(a,b)}).addClass("ngdialog-closing")):(h.$destroy(),A.closeDialogElement(a,b)),o[e]&&(o[e].resolve({id:e,value:b,$dialog:a,remainingDialogs:n}),delete o[e]),k[e]&&delete k[e],l.splice(l.indexOf(e),1),l.length||(z.body.unbind("keydown",A.onDocumentKeydown),m=!1)}},closeDialogElement:function(a,b){a.remove(),0===n&&(z.html.removeClass("ngdialog-open"),z.body.removeClass("ngdialog-open"),A.resetBodyPadding()),u.$broadcast("ngDialog.closed",a,b)},closeDialog:function(b,c){var d=b.data("$ngDialogPreCloseCallback");if(d&&a.isFunction(d)){var e=d.call(b,c);a.isObject(e)?e.closePromise?e.closePromise.then(function(){A.performCloseDialog(b,c)}):e.then(function(){A.performCloseDialog(b,c)},function(){}):e!==!1&&A.performCloseDialog(b,c)}else A.performCloseDialog(b,c)},onTrapFocusKeydown:function(b){var c,d=a.element(b.currentTarget);if(d.hasClass("ngdialog"))c=d;else if(c=A.getActiveDialog(),null===c)return;var e=9===b.keyCode,f=b.shiftKey===!0;e&&A.handleTab(c,b,f)},handleTab:function(a,b,c){var d=A.getFocusableElements(a);if(0===d.length)return document.activeElement&&document.activeElement.blur(),void 0;var e=document.activeElement,f=Array.prototype.indexOf.call(d,e),g=-1===f,h=0===f,i=f===d.length-1,j=!1;c?(g||h)&&(d[d.length-1].focus(),j=!0):(g||i)&&(d[0].focus(),j=!0),j&&(b.preventDefault(),b.stopPropagation())},autoFocus:function(a){var b=a[0],d=b.querySelector("*[autofocus]");if(null===d||(d.focus(),document.activeElement!==d)){var e=A.getFocusableElements(a);if(e.length>0)return e[0].focus(),void 0;var f=A.filterVisibleElements(b.querySelectorAll("h1,h2,h3,h4,h5,h6,p,span"));if(f.length>0){var g=f[0];c(g).attr("tabindex","-1").css("outline","0"),g.focus()}}},getFocusableElements:function(a){var b=a[0],c=b.querySelectorAll(h),d=A.filterTabbableElements(c);return A.filterVisibleElements(d)},filterTabbableElements:function(a){for(var b=[],d=0;d<a.length;d++){var e=a[d];"-1"!==c(e).attr("tabindex")&&b.push(e)}return b},filterVisibleElements:function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c];(d.offsetWidth>0||d.offsetHeight>0)&&b.push(d)}return b},getActiveDialog:function(){var a=document.querySelectorAll(".ngdialog");return 0===a.length?null:c(a[a.length-1])},applyAriaAttributes:function(a,b){if(b.ariaAuto){if(!b.ariaRole){var c=A.getFocusableElements(a).length>0?"dialog":"alertdialog";b.ariaRole=c}b.ariaLabelledBySelector||(b.ariaLabelledBySelector="h1,h2,h3,h4,h5,h6"),b.ariaDescribedBySelector||(b.ariaDescribedBySelector="article,section,p")}b.ariaRole&&a.attr("role",b.ariaRole),A.applyAriaAttribute(a,"aria-labelledby",b.ariaLabelledById,b.ariaLabelledBySelector),A.applyAriaAttribute(a,"aria-describedby",b.ariaDescribedById,b.ariaDescribedBySelector)},applyAriaAttribute:function(a,b,d,e){if(d&&a.attr(b,d),e){var f=a.attr("id"),g=a[0].querySelector(e);if(!g)return;var h=f+"-"+b;return c(g).attr("id",h),a.attr(b,h),h}},detectUIRouter:function(){try{return a.module("ui.router"),!0}catch(b){return!1}},getRouterLocationEventName:function(){return A.detectUIRouter()?"$stateChangeSuccess":"$locationChangeSuccess"}},B={open:function(f){function g(a,b){return u.$broadcast("ngDialog.templateLoading",a),t.get(a,b||{}).then(function(b){return u.$broadcast("ngDialog.templateLoaded",a),b.data||""})}function h(b){return b?a.isString(b)&&j.plain?b:"boolean"!=typeof j.cache||j.cache?g(b,{cache:q}):g(b,{cache:!1}):"Empty template"}var j=a.copy(b),p=++e,C="ngdialog"+p;l.push(C),f=f||{},a.extend(j,f);var D;o[C]=D=s.defer();var E;k[C]=E=a.isObject(j.scope)?j.scope.$new():u.$new();var F,G,H=a.extend({},j.resolve);return a.forEach(H,function(b,c){H[c]=a.isString(b)?y.get(b):y.invoke(b,null,null,c)}),s.all({template:h(j.template||j.templateUrl),locals:s.all(H)}).then(function(b){var e=b.template,f=b.locals;if(j.showClose&&(e+='<div class="ngdialog-close"></div>'),F=c('<div id="ngdialog'+p+'" class="ngdialog"></div>'),F.html(j.overlay?'<div class="ngdialog-overlay"></div><div class="ngdialog-content" role="document">'+e+"</div>":'<div class="ngdialog-content" role="document">'+e+"</div>"),F.data("$ngDialogOptions",j),E.ngDialogId=C,j.data&&a.isString(j.data)){var g=j.data.replace(/^\s*/,"")[0];E.ngDialogData="{"===g||"["===g?a.fromJson(j.data):j.data,E.ngDialogData.ngDialogId=C}else j.data&&a.isObject(j.data)&&(E.ngDialogData=j.data,E.ngDialogData.ngDialogId=C);if(j.controller&&(a.isString(j.controller)||a.isArray(j.controller)||a.isFunction(j.controller))){var h;j.controllerAs&&a.isString(j.controllerAs)&&(h=j.controllerAs);var k=x(j.controller,a.extend(f,{$scope:E,$element:F}),null,h);F.data("$ngDialogControllerController",k)}if(j.className&&F.addClass(j.className),j.disableAnimation&&F.addClass(i),G=j.appendTo&&a.isString(j.appendTo)?a.element(document.querySelector(j.appendTo)):z.body,A.applyAriaAttributes(F,j),j.preCloseCallback){var l;a.isFunction(j.preCloseCallback)?l=j.preCloseCallback:a.isString(j.preCloseCallback)&&E&&(a.isFunction(E[j.preCloseCallback])?l=E[j.preCloseCallback]:E.$parent&&a.isFunction(E.$parent[j.preCloseCallback])?l=E.$parent[j.preCloseCallback]:u&&a.isFunction(u[j.preCloseCallback])&&(l=u[j.preCloseCallback])),l&&F.data("$ngDialogPreCloseCallback",l)}if(E.closeThisDialog=function(a){A.closeDialog(F,a)},v(function(){var a=document.querySelectorAll(".ngdialog");A.deactivateAll(a),r(F)(E);var b=w.innerWidth-z.body.prop("clientWidth");z.html.addClass("ngdialog-open"),z.body.addClass("ngdialog-open");var c=b-(w.innerWidth-z.body.prop("clientWidth"));c>0&&A.setBodyPadding(c),G.append(F),A.activate(F),j.trapFocus&&A.autoFocus(F),j.name?u.$broadcast("ngDialog.opened",{dialog:F,name:j.name}):u.$broadcast("ngDialog.opened",F)}),m||(z.body.bind("keydown",A.onDocumentKeydown),m=!0),j.closeByNavigation){var o=A.getRouterLocationEventName();u.$on(o,function(){A.closeDialog(F)})}if(j.preserveFocus&&F.data("$ngDialogPreviousFocus",document.activeElement),d=function(a){var b=j.closeByDocument?c(a.target).hasClass("ngdialog-overlay"):!1,d=c(a.target).hasClass("ngdialog-close");(b||d)&&B.close(F.attr("id"),d?"$closeButton":"$document")},"undefined"!=typeof w.Hammer){var q=E.hammerTime=w.Hammer(F[0]);q.on("tap",d)}else F.bind("click",d);return n+=1,B}),{id:C,closePromise:D.promise,close:function(a){A.closeDialog(F,a)}}},openConfirm:function(b){var d=s.defer(),e={closeByEscape:!1,closeByDocument:!1};a.extend(e,b),e.scope=a.isObject(e.scope)?e.scope.$new():u.$new(),e.scope.confirm=function(a){d.resolve(a);var b=c(document.getElementById(f.id));A.performCloseDialog(b,a)};var f=B.open(e);return f.closePromise.then(function(a){return a?d.reject(a.value):d.reject()}),d.promise},isOpen:function(a){var b=c(document.getElementById(a));return b.length>0},close:function(a,b){var d=c(document.getElementById(a));if(d.length)A.closeDialog(d,b);else if("$escape"===a){var e=l[l.length-1];d=c(document.getElementById(e)),d.data("$ngDialogOptions").closeByEscape&&A.closeDialog(d,b)}else B.closeAll(b);return B},closeAll:function(a){for(var b=document.querySelectorAll(".ngdialog"),d=b.length-1;d>=0;d--){var e=b[d];A.closeDialog(c(e),a)}},getOpenDialogs:function(){return l},getDefaults:function(){return b}};return B}]}),b.directive("ngDialog",["ngDialog",function(b){return{restrict:"A",scope:{ngDialogScope:"="},link:function(c,d,e){d.on("click",function(d){d.preventDefault();var f=a.isDefined(c.ngDialogScope)?c.ngDialogScope:"noScope";a.isDefined(e.ngDialogClosePrevious)&&b.close(e.ngDialogClosePrevious);var g=b.getDefaults();b.open({template:e.ngDialog,className:e.ngDialogClass||g.className,controller:e.ngDialogController,controllerAs:e.ngDialogControllerAs,bindToController:e.ngDialogBindToController,scope:f,data:e.ngDialogData,showClose:"false"===e.ngDialogShowClose?!1:"true"===e.ngDialogShowClose?!0:g.showClose,closeByDocument:"false"===e.ngDialogCloseByDocument?!1:"true"===e.ngDialogCloseByDocument?!0:g.closeByDocument,closeByEscape:"false"===e.ngDialogCloseByEscape?!1:"true"===e.ngDialogCloseByEscape?!0:g.closeByEscape,overlay:"false"===e.ngDialogOverlay?!1:"true"===e.ngDialogOverlay?!0:g.overlay,preCloseCallback:e.ngDialogPreCloseCallback||g.preCloseCallback})})}}}]),b}); |
{ | ||
"name": "ng-dialog", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"homepage": "https://github.com/likeastore/ngDialog", | ||
@@ -37,5 +37,5 @@ "description": "Modal dialogs and popups provider for Angular.js applications", | ||
"dependencies": { | ||
"angular": "1.3.x" | ||
}, | ||
"devDependencies": { | ||
"angular": "^1.4.x", | ||
"grunt": "~0.4.2", | ||
@@ -42,0 +42,0 @@ "grunt-contrib-cssmin": "^0.9.0", |
@@ -0,1 +1,2 @@ | ||
<!-- ### LOOKING FOR MAINTAINER. PLEASE PING [@voronianski](https://twitter.com/voronianski)! --> | ||
# ngDialog | ||
@@ -8,5 +9,6 @@ | ||
> Modal dialogs and popups provider for [Angular.js](http://angularjs.org/) applications. | ||
ngDialog is small (~2Kb), has minimalistic API, highly customizable through themes and has only Angular.js as dependency. | ||
ngDialog is ~10Kb, has minimalistic API, highly customizable through themes and has only Angular.js as dependency. | ||
@@ -72,2 +74,24 @@ ### [Demo](http://likeastore.github.io/ngDialog) | ||
##### Pro Tip about templates | ||
It's not always necessary to place your external html template inside ``<script>`` tag. You could put these templates into ``$templateCache`` like this: | ||
```javascript | ||
angular.module('dialog.templates').run([$templateCache, function($templateCache) { | ||
$templateCache.put('templateId', 'template content'); | ||
}]); | ||
``` | ||
Then you it would be possible to include ``dialog.templates`` module into dependencies of your main module and start using this template as ``templateId``. | ||
There is no need to do these actions manually. | ||
You could use one of the plugins specifically for these purposes. They are available for different build systems including most popular Gulp / Grunt: | ||
- [gulp-angular-templatecache](https://github.com/miickel/gulp-angular-templatecache) | ||
- [gulp-ng-html2js](https://www.npmjs.com/package/gulp-ng-html2js) | ||
- [grunt-html2js](https://github.com/karlgoldstein/grunt-html2js) | ||
- [grunt-html2js](https://www.npmjs.com/package/broccoli-html2js) | ||
You could find more detailed examples on each of these pages. | ||
##### ``plain {Boolean}`` | ||
@@ -106,2 +130,8 @@ | ||
##### ``controllerAs {String} `` | ||
You could optionally specify `controllerAs` parameter for your controller. Then inside your template it will be possible to refer this controller by value specified by `controllerAs`. | ||
Usage of `controllerAs` syntax is currently recommended by Angular team. | ||
##### ``resolve {Object.<string, function>=}`` | ||
@@ -172,2 +202,4 @@ An optional map of dependencies which should be injected into the controller. | ||
Additionally, you will have dialog id available as ``$scope.ngDialogId``. If you are using ``$scope.ngDialogData``, it'll be also available under ``$scope.ngDialogData.ngDialogId``. | ||
##### ``className {String}`` | ||
@@ -188,2 +220,6 @@ | ||
##### ``disableAnimation {Boolean}`` | ||
If ``true`` then animation for the dialog will be disabled, default ``false``. | ||
##### ``overlay {Boolean}`` | ||
@@ -281,3 +317,3 @@ | ||
##### ``ariaLaballedById {String}`` | ||
##### ``ariaLabelledById {String}`` | ||
@@ -288,3 +324,3 @@ Specifies the value for the ``aria-labelledby`` attribute that should be applied to the dialog element. Default value is ``null`` (unspecified) | ||
##### ``ariaLaballedBySelector {String}`` | ||
##### ``ariaLabelledBySelector {String}`` | ||
@@ -388,3 +424,3 @@ Specifies the CSS selector for the element to be referenced by the ``aria-labelledby`` attribute on the dialog element. Default value is ``null`` (unspecified) | ||
Method accepts dialog's ``id`` and returns a ``Boolean`` value indicating whether the specified dialog is open. | ||
Method accepts dialog's ``id`` and returns a ``Boolean`` value indicating whether the specified dialog is open. | ||
@@ -405,2 +441,22 @@ === | ||
### ``.getOpenDialogs()`` | ||
Method that returns array which includes ids of opened dialogs. | ||
=== | ||
### ``.setForceHtmlReload({Boolean})`` | ||
Adds additional listener on every ``$locationChangeSuccess`` event and gets update version of ``html`` into dialog. Maybe useful in some rare cases when you're dependant on DOM changes, defaults to ``false``. Use it in module's config as provider instance: | ||
```javascript | ||
var app = angular.module('exampleApp', ['ngDialog']); | ||
app.config(function (ngDialogProvider) { | ||
ngDialogProvider.setForceHtmlReload(true); | ||
}); | ||
``` | ||
=== | ||
### ``.setForceBodyReload({Boolean})`` | ||
@@ -434,2 +490,5 @@ | ||
You could optionally use ``ng-dialog-bind-to-controller`` to bind scope you've defined via parameter of directive to controller. | ||
More information about bindToController is available [here](http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html). | ||
Directive contains one more additional but very useful option, it's an attribute named ``ng-dialog-close-previous``. It allows you to close previously opened dialogs automatically. | ||
@@ -457,2 +516,10 @@ | ||
Additionally we trigger following 2 events related to loading of template for dialog: | ||
- ``ngDialog.templateLoading`` | ||
- ``ngDialog.templateLoaded`` | ||
In case you are loading your templates from external location, you could use above events to show some kind of loader. | ||
## Themes | ||
@@ -492,9 +559,9 @@ | ||
_ngDialog_ is available for public on [cdnjs](http://cdnjs.com/libraries/ng-dialog). For example, please use following urls for version ``0.3.12``. | ||
_ngDialog_ is available for public on [cdnjs](http://cdnjs.com/libraries/ng-dialog). For example, please use following urls for version ``0.4.0``. | ||
```html | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.3.12/css/ngDialog.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.3.12/css/ngDialog-theme-default.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.3.12/css/ngDialog-theme-plain.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.3.12/js/ngDialog.min.js | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.4.0/css/ngDialog.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.4.0/css/ngDialog-theme-default.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.4.0/css/ngDialog-theme-plain.min.css | ||
//cdnjs.cloudflare.com/ajax/libs/ng-dialog/0.4.0/js/ngDialog.min.js | ||
``` | ||
@@ -501,0 +568,0 @@ |
@@ -83,2 +83,25 @@ describe('ngDialog', function () { | ||
describe('with already cached template URL', function () { | ||
var elm; | ||
beforeEach(inject(function (ngDialog, $timeout, $document, $httpBackend, $compile, $rootScope) { | ||
$httpBackend.whenGET('cached.html').respond('<div><p>some text {{1 + 1}}</p></div>'); | ||
$compile('<div><div ng-include src="\'cached.html\'"></div></div>')($rootScope); | ||
$rootScope.$digest(); | ||
$httpBackend.flush(); | ||
var id = ngDialog.open({ | ||
templateUrl: 'cached.html' | ||
}).id; | ||
$timeout.flush(); | ||
elm = $document[0].getElementById(id); | ||
})); | ||
it('should have compiled the html', inject(function () { | ||
expect(elm.textContent).toEqual('some text 2'); | ||
})); | ||
}); | ||
describe('controller instantiation', function () { | ||
@@ -85,0 +108,0 @@ var Ctrl; |
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 not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
136167
0
30
1640
574
13
- Removedangular@1.3.x
- Removedangular@1.3.20(transitive)