{"version":3,"sources":["modules/modal.js"],"names":["angular","placement","provider","templateUrl","this","defaults","template","contentTemplate","container","element","backdrop","keyboard","html","show","size","zIndex","$get","forEach","requestAnimationFrame","bodyElement","backdropCount","dialogBaseZindex","validSizes","ModalFactory","config","$modal","scope","$emit","options","prefixEvent","isDefined","onShow","isFunction","leaveAnimateCallback","animation","removeClass","prefixClass","onHide","length","$isShown","unbindBackdropEvents","modalElement","off","hideOnBackdropClick","backdropElement","preventEventDefault","bindKeyboardEvents","on","$onKeyUp","focus","evt","preventDefault","modalScope","$destroy","$element","parseInt","backdropBaseZindex","compile","$scope","$new","$rootScope","id","$id","attr","key","$show","$sce","trustAsHtml","$$postDigest","hide","toggle","left","bottom","right","promise","css","compileData","init","data","destroy","destroyModalElement","parent","after","isElement","z-index","link","clonedElement","onBeforeShow","display","defaultPrevented","addClass","customClass","findElement","$animate","enter","minor","backdropAnimation","el","enterAnimateCallback","then","safeDigest","bindBackdropEvents","version","leave","onBeforeHide","unbindKeyboardEvents","which","directive","$root","$$phase","$digest","restrict","query","document","querySelectorAll","lg","sm","$window","setTimeout","body","$options","falseValueRegExp","test","bsKey","modalClass","$observe","charAt","newValue","oldValue","$eval","$watch","isObject","extend","bsModal","modal","trigger","$on"],"mappings":"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","file":"modal.min.js","sourcesContent":["'use strict';\n\nangular.module('mgcrea.ngStrap.modal', ['mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions'])\n\n .provider('$modal', function () {\n\n var defaults = this.defaults = {\n animation: 'am-fade',\n backdropAnimation: 'am-fade',\n customClass: '',\n prefixClass: 'modal',\n prefixEvent: 'modal',\n placement: 'top',\n templateUrl: 'modal/modal.tpl.html',\n template: '',\n contentTemplate: false,\n container: false,\n element: null,\n backdrop: true,\n keyboard: true,\n html: false,\n show: true,\n size: null,\n zIndex: null\n };\n\n this.$get = function ($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {\n\n var forEach = angular.forEach;\n var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;\n var bodyElement = angular.element($window.document.body);\n\n var backdropCount = 0;\n var dialogBaseZindex = 1050;\n var backdropBaseZindex = 1040;\n\n var validSizes = {\n lg: 'modal-lg',\n sm: 'modal-sm'\n };\n\n function ModalFactory (config) {\n\n var $modal = {};\n\n // Common vars\n var options = $modal.$options = angular.extend({}, defaults, config);\n var promise = $modal.$promise = $bsCompiler.compile(options);\n var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();\n\n if (!options.element && !options.container) {\n options.container = 'body';\n }\n\n if (options.zIndex) {\n dialogBaseZindex = parseInt(options.zIndex, 10);\n backdropBaseZindex = dialogBaseZindex - 10;\n }\n\n // Store $id to identify the triggering element in events\n // give priority to options.id, otherwise, try to use\n // element id if defined\n $modal.$id = options.id || options.element && options.element.attr('id') || '';\n\n // Support scope as string options\n forEach(['title', 'content'], function (key) {\n if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);\n });\n\n // Provide scope helpers\n scope.$hide = function () {\n scope.$$postDigest(function () {\n $modal.hide();\n });\n };\n scope.$show = function () {\n scope.$$postDigest(function () {\n $modal.show();\n });\n };\n scope.$toggle = function () {\n scope.$$postDigest(function () {\n $modal.toggle();\n });\n };\n // Publish isShown as a protected var on scope\n $modal.$isShown = scope.$isShown = false;\n\n // Fetch, compile then initialize modal\n var compileData;\n var modalElement;\n var modalScope;\n var backdropElement = angular.element('
');\n backdropElement.css({position: 'fixed', top: '0px', left: '0px', bottom: '0px', right: '0px'});\n promise.then(function (data) {\n compileData = data;\n $modal.init();\n });\n\n $modal.init = function () {\n\n // Options: show\n if (options.show) {\n scope.$$postDigest(function () {\n $modal.show();\n });\n }\n\n };\n\n $modal.destroy = function () {\n\n // Remove element\n destroyModalElement();\n\n // remove backdrop element\n if (backdropElement) {\n backdropElement.remove();\n backdropElement = null;\n }\n\n // Destroy scope\n scope.$destroy();\n };\n\n $modal.show = function () {\n if ($modal.$isShown) return;\n\n var parent;\n var after;\n if (angular.isElement(options.container)) {\n parent = options.container;\n after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;\n } else {\n if (options.container) {\n parent = findElement(options.container);\n after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;\n } else {\n parent = null;\n after = options.element;\n }\n }\n\n // destroy any existing modal elements\n if (modalElement) destroyModalElement();\n\n // create a new scope, so we can destroy it and all child scopes\n // when destroying the modal element\n modalScope = $modal.$scope.$new();\n // Fetch a cloned element linked from template (noop callback is required)\n modalElement = $modal.$element = compileData.link(modalScope, function (clonedElement, scope) {});\n\n if (options.backdrop) {\n // set z-index\n modalElement.css({'z-index': dialogBaseZindex + (backdropCount * 20)});\n backdropElement.css({'z-index': backdropBaseZindex + (backdropCount * 20)});\n\n // increment number of backdrops\n backdropCount++;\n }\n\n if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {\n options.onBeforeShow($modal);\n }\n\n // Set the initial positioning.\n modalElement.css({display: 'block'}).addClass(options.placement);\n\n // Options: customClass\n if (options.customClass) {\n modalElement.addClass(options.customClass);\n }\n\n // Options: size\n if (options.size && validSizes[options.size]) {\n angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);\n }\n\n // Options: animation\n if (options.animation) {\n if (options.backdrop) {\n backdropElement.addClass(options.backdropAnimation);\n }\n modalElement.addClass(options.animation);\n }\n\n if (options.backdrop) {\n $animate.enter(backdropElement, bodyElement, null);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.enter(modalElement, parent, after, enterAnimateCallback);\n } else {\n $animate.enter(modalElement, parent, after).then(enterAnimateCallback);\n }\n\n $modal.$isShown = scope.$isShown = true;\n safeDigest(scope);\n // Focus once the enter-animation has started\n // Weird PhantomJS bug hack\n var el = modalElement[0];\n requestAnimationFrame(function () {\n el.focus();\n });\n\n bodyElement.addClass(options.prefixClass + '-open');\n if (options.animation) {\n bodyElement.addClass(options.prefixClass + '-with-' + options.animation);\n }\n\n // Bind events\n bindBackdropEvents();\n bindKeyboardEvents();\n };\n\n function enterAnimateCallback () {\n scope.$emit(options.prefixEvent + '.show', $modal);\n if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {\n options.onShow($modal);\n }\n }\n\n $modal.hide = function () {\n if (!$modal.$isShown) return;\n\n if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {\n return;\n }\n if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {\n options.onBeforeHide($modal);\n }\n\n // Support v1.2+ $animate\n // https://github.com/angular/angular.js/issues/11713\n if (angular.version.minor <= 2) {\n $animate.leave(modalElement, leaveAnimateCallback);\n } else {\n $animate.leave(modalElement).then(leaveAnimateCallback);\n }\n\n if (options.backdrop) {\n // decrement number of backdrops\n backdropCount--;\n $animate.leave(backdropElement);\n }\n $modal.$isShown = scope.$isShown = false;\n safeDigest(scope);\n\n // Unbind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n };\n\n function leaveAnimateCallback () {\n scope.$emit(options.prefixEvent + '.hide', $modal);\n if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {\n options.onHide($modal);\n }\n if (findElement('.modal').length <= 0) {\n bodyElement.removeClass(options.prefixClass + '-open');\n }\n if (options.animation) {\n bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);\n }\n }\n\n $modal.toggle = function () {\n if ($modal.$isShown) {\n $modal.hide();\n } else {\n $modal.show();\n }\n };\n\n $modal.focus = function () {\n modalElement[0].focus();\n };\n\n // Protected methods\n\n $modal.$onKeyUp = function (evt) {\n\n if (evt.which === 27 && $modal.$isShown) {\n $modal.hide();\n evt.stopPropagation();\n }\n\n };\n\n function bindBackdropEvents () {\n if (options.backdrop) {\n modalElement.on('click', hideOnBackdropClick);\n backdropElement.on('click', hideOnBackdropClick);\n backdropElement.on('wheel', preventEventDefault);\n }\n }\n\n function unbindBackdropEvents () {\n if (options.backdrop) {\n modalElement.off('click', hideOnBackdropClick);\n backdropElement.off('click', hideOnBackdropClick);\n backdropElement.off('wheel', preventEventDefault);\n }\n }\n\n function bindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.on('keyup', $modal.$onKeyUp);\n }\n }\n\n function unbindKeyboardEvents () {\n if (options.keyboard) {\n modalElement.off('keyup', $modal.$onKeyUp);\n }\n }\n\n // Private helpers\n\n function hideOnBackdropClick (evt) {\n if (evt.target !== evt.currentTarget) return;\n if (options.backdrop === 'static') {\n $modal.focus();\n } else {\n $modal.hide();\n }\n }\n\n function preventEventDefault (evt) {\n evt.preventDefault();\n }\n\n function destroyModalElement () {\n if ($modal.$isShown && modalElement !== null) {\n // un-bind events\n unbindBackdropEvents();\n unbindKeyboardEvents();\n }\n\n if (modalScope) {\n modalScope.$destroy();\n modalScope = null;\n }\n\n if (modalElement) {\n modalElement.remove();\n modalElement = $modal.$element = null;\n }\n }\n\n return $modal;\n\n }\n\n // Helper functions\n\n function safeDigest (scope) {\n /* eslint-disable no-unused-expressions */\n scope.$$phase || (scope.$root && scope.$root.$$phase) || scope.$digest();\n /* eslint-enable no-unused-expressions */\n }\n\n function findElement (query, element) {\n return angular.element((element || document).querySelectorAll(query));\n }\n\n return ModalFactory;\n\n };\n\n })\n\n .directive('bsModal', function ($window, $sce, $parse, $modal) {\n\n return {\n restrict: 'EAC',\n scope: true,\n link: function postLink (scope, element, attr, transclusion) {\n\n // Directive options\n var options = {scope: scope, element: element, show: false};\n angular.forEach(['template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size', 'zIndex'], function (key) {\n if (angular.isDefined(attr[key])) options[key] = attr[key];\n });\n\n // Options: alias modalClass to customClass\n if (options.modalClass) {\n options.customClass = options.modalClass;\n }\n\n // use string regex match boolean attr falsy values, leave truthy values be\n var falseValueRegExp = /^(false|0|)$/i;\n angular.forEach(['backdrop', 'keyboard', 'html', 'container'], function (key) {\n if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;\n });\n\n // bind functions from the attrs to the show and hide events\n angular.forEach(['onBeforeShow', 'onShow', 'onBeforeHide', 'onHide'], function (key) {\n var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);\n if (angular.isDefined(attr[bsKey])) {\n options[key] = scope.$eval(attr[bsKey]);\n }\n });\n\n // Support scope as data-attrs\n angular.forEach(['title', 'content'], function (key) {\n if (attr[key]) {\n attr.$observe(key, function (newValue, oldValue) {\n scope[key] = $sce.trustAsHtml(newValue);\n });\n }\n });\n\n // Support scope as an object\n if (attr.bsModal) {\n scope.$watch(attr.bsModal, function (newValue, oldValue) {\n if (angular.isObject(newValue)) {\n angular.extend(scope, newValue);\n } else {\n scope.content = newValue;\n }\n }, true);\n }\n\n // Initialize modal\n var modal = $modal(options);\n\n // Trigger\n element.on(attr.trigger || 'click', modal.toggle);\n\n // Garbage collection\n scope.$on('$destroy', function () {\n if (modal) modal.destroy();\n options = null;\n modal = null;\n });\n\n }\n };\n\n });\n"]}