123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- /**
- * angular-strap
- * @version v2.3.9 - 2016-06-10
- * @link http://mgcrea.github.io/angular-strap
- * @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
- * @license MIT License, http://www.opensource.org/licenses/MIT
- */
- 'use strict';
- angular.module('mgcrea.ngStrap.modal', [ 'mgcrea.ngStrap.core', 'mgcrea.ngStrap.helpers.dimensions' ]).provider('$modal', function() {
- var defaults = this.defaults = {
- animation: 'am-fade',
- backdropAnimation: 'am-fade',
- customClass: '',
- prefixClass: 'modal',
- prefixEvent: 'modal',
- placement: 'top',
- templateUrl: 'modal/modal.tpl.html',
- template: '',
- contentTemplate: false,
- container: false,
- element: null,
- backdrop: true,
- keyboard: true,
- html: false,
- show: true,
- size: null
- };
- this.$get = [ '$window', '$rootScope', '$bsCompiler', '$animate', '$timeout', '$sce', 'dimensions', function($window, $rootScope, $bsCompiler, $animate, $timeout, $sce, dimensions) {
- var forEach = angular.forEach;
- var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;
- var bodyElement = angular.element($window.document.body);
- var backdropCount = 0;
- var dialogBaseZindex = 1050;
- var backdropBaseZindex = 1040;
- var validSizes = {
- lg: 'modal-lg',
- sm: 'modal-sm'
- };
- function ModalFactory(config) {
- var $modal = {};
- var options = $modal.$options = angular.extend({}, defaults, config);
- var promise = $modal.$promise = $bsCompiler.compile(options);
- var scope = $modal.$scope = options.scope && options.scope.$new() || $rootScope.$new();
- if (!options.element && !options.container) {
- options.container = 'body';
- }
- $modal.$id = options.id || options.element && options.element.attr('id') || '';
- forEach([ 'title', 'content' ], function(key) {
- if (options[key]) scope[key] = $sce.trustAsHtml(options[key]);
- });
- scope.$hide = function() {
- scope.$$postDigest(function() {
- $modal.hide();
- });
- };
- scope.$show = function() {
- scope.$$postDigest(function() {
- $modal.show();
- });
- };
- scope.$toggle = function() {
- scope.$$postDigest(function() {
- $modal.toggle();
- });
- };
- $modal.$isShown = scope.$isShown = false;
- var compileData;
- var modalElement;
- var modalScope;
- var backdropElement = angular.element('<div class="' + options.prefixClass + '-backdrop"/>');
- backdropElement.css({
- position: 'fixed',
- top: '0px',
- left: '0px',
- bottom: '0px',
- right: '0px'
- });
- promise.then(function(data) {
- compileData = data;
- $modal.init();
- });
- $modal.init = function() {
- if (options.show) {
- scope.$$postDigest(function() {
- $modal.show();
- });
- }
- };
- $modal.destroy = function() {
- destroyModalElement();
- if (backdropElement) {
- backdropElement.remove();
- backdropElement = null;
- }
- scope.$destroy();
- };
- $modal.show = function() {
- if ($modal.$isShown) return;
- var parent;
- var after;
- if (angular.isElement(options.container)) {
- parent = options.container;
- after = options.container[0].lastChild ? angular.element(options.container[0].lastChild) : null;
- } else {
- if (options.container) {
- parent = findElement(options.container);
- after = parent[0] && parent[0].lastChild ? angular.element(parent[0].lastChild) : null;
- } else {
- parent = null;
- after = options.element;
- }
- }
- if (modalElement) destroyModalElement();
- modalScope = $modal.$scope.$new();
- modalElement = $modal.$element = compileData.link(modalScope, function(clonedElement, scope) {});
- if (options.backdrop) {
- modalElement.css({
- 'z-index': dialogBaseZindex + backdropCount * 20
- });
- backdropElement.css({
- 'z-index': backdropBaseZindex + backdropCount * 20
- });
- backdropCount++;
- }
- if (scope.$emit(options.prefixEvent + '.show.before', $modal).defaultPrevented) {
- return;
- }
- if (angular.isDefined(options.onBeforeShow) && angular.isFunction(options.onBeforeShow)) {
- options.onBeforeShow($modal);
- }
- modalElement.css({
- display: 'block'
- }).addClass(options.placement);
- if (options.customClass) {
- modalElement.addClass(options.customClass);
- }
- if (options.size && validSizes[options.size]) {
- angular.element(findElement('.modal-dialog', modalElement[0])).addClass(validSizes[options.size]);
- }
- if (options.animation) {
- if (options.backdrop) {
- backdropElement.addClass(options.backdropAnimation);
- }
- modalElement.addClass(options.animation);
- }
- if (options.backdrop) {
- $animate.enter(backdropElement, bodyElement, null);
- }
- if (angular.version.minor <= 2) {
- $animate.enter(modalElement, parent, after, enterAnimateCallback);
- } else {
- $animate.enter(modalElement, parent, after).then(enterAnimateCallback);
- }
- $modal.$isShown = scope.$isShown = true;
- safeDigest(scope);
- var el = modalElement[0];
- requestAnimationFrame(function() {
- el.focus();
- });
- bodyElement.addClass(options.prefixClass + '-open');
- if (options.animation) {
- bodyElement.addClass(options.prefixClass + '-with-' + options.animation);
- }
- bindBackdropEvents();
- bindKeyboardEvents();
- };
- function enterAnimateCallback() {
- scope.$emit(options.prefixEvent + '.show', $modal);
- if (angular.isDefined(options.onShow) && angular.isFunction(options.onShow)) {
- options.onShow($modal);
- }
- }
- $modal.hide = function() {
- if (!$modal.$isShown) return;
- if (scope.$emit(options.prefixEvent + '.hide.before', $modal).defaultPrevented) {
- return;
- }
- if (angular.isDefined(options.onBeforeHide) && angular.isFunction(options.onBeforeHide)) {
- options.onBeforeHide($modal);
- }
- if (angular.version.minor <= 2) {
- $animate.leave(modalElement, leaveAnimateCallback);
- } else {
- $animate.leave(modalElement).then(leaveAnimateCallback);
- }
- if (options.backdrop) {
- backdropCount--;
- $animate.leave(backdropElement);
- }
- $modal.$isShown = scope.$isShown = false;
- safeDigest(scope);
- unbindBackdropEvents();
- unbindKeyboardEvents();
- };
- function leaveAnimateCallback() {
- scope.$emit(options.prefixEvent + '.hide', $modal);
- if (angular.isDefined(options.onHide) && angular.isFunction(options.onHide)) {
- options.onHide($modal);
- }
- bodyElement.removeClass(options.prefixClass + '-open');
- if (options.animation) {
- bodyElement.removeClass(options.prefixClass + '-with-' + options.animation);
- }
- }
- $modal.toggle = function() {
- if ($modal.$isShown) {
- $modal.hide();
- } else {
- $modal.show();
- }
- };
- $modal.focus = function() {
- modalElement[0].focus();
- };
- $modal.$onKeyUp = function(evt) {
- if (evt.which === 27 && $modal.$isShown) {
- $modal.hide();
- evt.stopPropagation();
- }
- };
- function bindBackdropEvents() {
- if (options.backdrop) {
- modalElement.on('click', hideOnBackdropClick);
- backdropElement.on('click', hideOnBackdropClick);
- backdropElement.on('wheel', preventEventDefault);
- }
- }
- function unbindBackdropEvents() {
- if (options.backdrop) {
- modalElement.off('click', hideOnBackdropClick);
- backdropElement.off('click', hideOnBackdropClick);
- backdropElement.off('wheel', preventEventDefault);
- }
- }
- function bindKeyboardEvents() {
- if (options.keyboard) {
- modalElement.on('keyup', $modal.$onKeyUp);
- }
- }
- function unbindKeyboardEvents() {
- if (options.keyboard) {
- modalElement.off('keyup', $modal.$onKeyUp);
- }
- }
- function hideOnBackdropClick(evt) {
- if (evt.target !== evt.currentTarget) return;
- if (options.backdrop === 'static') {
- $modal.focus();
- } else {
- $modal.hide();
- }
- }
- function preventEventDefault(evt) {
- evt.preventDefault();
- }
- function destroyModalElement() {
- if ($modal.$isShown && modalElement !== null) {
- unbindBackdropEvents();
- unbindKeyboardEvents();
- }
- if (modalScope) {
- modalScope.$destroy();
- modalScope = null;
- }
- if (modalElement) {
- modalElement.remove();
- modalElement = $modal.$element = null;
- }
- }
- return $modal;
- }
- function safeDigest(scope) {
- scope.$$phase || scope.$root && scope.$root.$$phase || scope.$digest();
- }
- function findElement(query, element) {
- return angular.element((element || document).querySelectorAll(query));
- }
- return ModalFactory;
- } ];
- }).directive('bsModal', [ '$window', '$sce', '$parse', '$modal', function($window, $sce, $parse, $modal) {
- return {
- restrict: 'EAC',
- scope: true,
- link: function postLink(scope, element, attr, transclusion) {
- var options = {
- scope: scope,
- element: element,
- show: false
- };
- angular.forEach([ 'template', 'templateUrl', 'controller', 'controllerAs', 'contentTemplate', 'placement', 'backdrop', 'keyboard', 'html', 'container', 'animation', 'backdropAnimation', 'id', 'prefixEvent', 'prefixClass', 'customClass', 'modalClass', 'size' ], function(key) {
- if (angular.isDefined(attr[key])) options[key] = attr[key];
- });
- if (options.modalClass) {
- options.customClass = options.modalClass;
- }
- var falseValueRegExp = /^(false|0|)$/i;
- angular.forEach([ 'backdrop', 'keyboard', 'html', 'container' ], function(key) {
- if (angular.isDefined(attr[key]) && falseValueRegExp.test(attr[key])) options[key] = false;
- });
- angular.forEach([ 'onBeforeShow', 'onShow', 'onBeforeHide', 'onHide' ], function(key) {
- var bsKey = 'bs' + key.charAt(0).toUpperCase() + key.slice(1);
- if (angular.isDefined(attr[bsKey])) {
- options[key] = scope.$eval(attr[bsKey]);
- }
- });
- angular.forEach([ 'title', 'content' ], function(key) {
- if (attr[key]) {
- attr.$observe(key, function(newValue, oldValue) {
- scope[key] = $sce.trustAsHtml(newValue);
- });
- }
- });
- if (attr.bsModal) {
- scope.$watch(attr.bsModal, function(newValue, oldValue) {
- if (angular.isObject(newValue)) {
- angular.extend(scope, newValue);
- } else {
- scope.content = newValue;
- }
- }, true);
- }
- var modal = $modal(options);
- element.on(attr.trigger || 'click', modal.toggle);
- scope.$on('$destroy', function() {
- if (modal) modal.destroy();
- options = null;
- modal = null;
- });
- }
- };
- } ]);
|