| /* =========================================================== |
| * bootstrap-modal.js v2.1 |
| * =========================================================== |
| * Copyright 2012 Jordan Schroter |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * ========================================================== */ |
| |
| |
| !function ($) { |
| |
| "use strict"; // jshint ;_; |
| |
| /* MODAL CLASS DEFINITION |
| * ====================== */ |
| |
| var Modal = function (element, options) { |
| this.init(element, options); |
| }; |
| |
| Modal.prototype = { |
| |
| constructor: Modal, |
| |
| init: function (element, options) { |
| this.options = options; |
| |
| this.$element = $(element) |
| .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)); |
| |
| this.options.remote && this.$element.find('.modal-body').load(this.options.remote); |
| |
| var manager = typeof this.options.manager === 'function' ? |
| this.options.manager.call(this) : this.options.manager; |
| |
| manager = manager.appendModal ? |
| manager : $(manager).modalmanager().data('modalmanager'); |
| |
| manager.appendModal(this); |
| }, |
| |
| toggle: function () { |
| return this[!this.isShown ? 'show' : 'hide'](); |
| }, |
| |
| show: function () { |
| var e = $.Event('show'); |
| |
| if (this.isShown) return; |
| |
| this.$element.trigger(e); |
| |
| if (e.isDefaultPrevented()) return; |
| |
| this.escape(); |
| |
| this.tab(); |
| |
| this.options.loading && this.loading(); |
| }, |
| |
| hide: function (e) { |
| e && e.preventDefault(); |
| |
| e = $.Event('hide'); |
| |
| this.$element.trigger(e); |
| |
| if (!this.isShown || e.isDefaultPrevented()) return (this.isShown = false); |
| |
| this.isShown = false; |
| |
| this.escape(); |
| |
| this.tab(); |
| |
| this.isLoading && this.loading(); |
| |
| $(document).off('focusin.modal'); |
| |
| this.$element |
| .removeClass('in') |
| .removeClass('animated') |
| .removeClass(this.options.attentionAnimation) |
| .removeClass('modal-overflow') |
| .attr('aria-hidden', true); |
| |
| $.support.transition && this.$element.hasClass('fade') ? |
| this.hideWithTransition() : |
| this.hideModal(); |
| }, |
| |
| layout: function () { |
| var prop = this.options.height ? 'height' : 'max-height', |
| value = this.options.height || this.options.maxHeight; |
| |
| if (this.options.width){ |
| this.$element.css('width', this.options.width); |
| |
| var that = this; |
| this.$element.css('margin-left', function () { |
| if (/%/ig.test(that.options.width)){ |
| return -(parseInt(that.options.width) / 2) + '%'; |
| } else { |
| return -($(this).width() / 2) + 'px'; |
| } |
| }); |
| } else { |
| this.$element.css('width', ''); |
| this.$element.css('margin-left', ''); |
| } |
| |
| this.$element.find('.modal-body') |
| .css('overflow', '') |
| .css(prop, ''); |
| |
| var modalOverflow = $(window).height() - 10 < this.$element.height(); |
| |
| if (value){ |
| this.$element.find('.modal-body') |
| .css('overflow', 'auto') |
| .css(prop, value); |
| } |
| |
| if (modalOverflow || this.options.modalOverflow) { |
| this.$element |
| .css('margin-top', 0) |
| .addClass('modal-overflow'); |
| } else { |
| this.$element |
| .css('margin-top', 0 - this.$element.height() / 2) |
| .removeClass('modal-overflow'); |
| } |
| }, |
| |
| tab: function () { |
| var that = this; |
| |
| if (this.isShown && this.options.consumeTab) { |
| this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) { |
| if (e.keyCode && e.keyCode == 9){ |
| var $next = $(this), |
| $rollover = $(this); |
| |
| that.$element.find('[data-tabindex]:enabled:not([readonly])').each(function (e) { |
| if (!e.shiftKey){ |
| $next = $next.data('tabindex') < $(this).data('tabindex') ? |
| $next = $(this) : |
| $rollover = $(this); |
| } else { |
| $next = $next.data('tabindex') > $(this).data('tabindex') ? |
| $next = $(this) : |
| $rollover = $(this); |
| } |
| }); |
| |
| $next[0] !== $(this)[0] ? |
| $next.focus() : $rollover.focus(); |
| |
| e.preventDefault(); |
| } |
| }); |
| } else if (!this.isShown) { |
| this.$element.off('keydown.tabindex.modal'); |
| } |
| }, |
| |
| escape: function () { |
| var that = this; |
| if (this.isShown && this.options.keyboard) { |
| if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1); |
| |
| this.$element.on('keyup.dismiss.modal', function (e) { |
| e.which == 27 && that.hide(); |
| }); |
| } else if (!this.isShown) { |
| this.$element.off('keyup.dismiss.modal') |
| } |
| }, |
| |
| hideWithTransition: function () { |
| var that = this |
| , timeout = setTimeout(function () { |
| that.$element.off($.support.transition.end); |
| that.hideModal(); |
| }, 500); |
| |
| this.$element.one($.support.transition.end, function () { |
| clearTimeout(timeout); |
| that.hideModal(); |
| }); |
| }, |
| |
| hideModal: function () { |
| this.$element |
| .hide() |
| .trigger('hidden'); |
| |
| var prop = this.options.height ? 'height' : 'max-height'; |
| var value = this.options.height || this.options.maxHeight; |
| |
| if (value){ |
| this.$element.find('.modal-body') |
| .css('overflow', '') |
| .css(prop, ''); |
| } |
| |
| }, |
| |
| removeLoading: function () { |
| this.$loading.remove(); |
| this.$loading = null; |
| this.isLoading = false; |
| }, |
| |
| loading: function (callback) { |
| callback = callback || function () {}; |
| |
| var animate = this.$element.hasClass('fade') ? 'fade' : ''; |
| |
| if (!this.isLoading) { |
| var doAnimate = $.support.transition && animate; |
| |
| this.$loading = $('<div class="loading-mask ' + animate + '">') |
| .append(this.options.spinner) |
| .appendTo(this.$element); |
| |
| if (doAnimate) this.$loading[0].offsetWidth; // force reflow |
| |
| this.$loading.addClass('in'); |
| |
| this.isLoading = true; |
| |
| doAnimate ? |
| this.$loading.one($.support.transition.end, callback) : |
| callback(); |
| |
| } else if (this.isLoading && this.$loading) { |
| this.$loading.removeClass('in'); |
| |
| var that = this; |
| $.support.transition && this.$element.hasClass('fade')? |
| this.$loading.one($.support.transition.end, function () { that.removeLoading() }) : |
| that.removeLoading(); |
| |
| } else if (callback) { |
| callback(this.isLoading); |
| } |
| }, |
| |
| focus: function () { |
| var $focusElem = this.$element.find(this.options.focusOn); |
| |
| $focusElem = $focusElem.length ? $focusElem : this.$element; |
| |
| $focusElem.focus(); |
| }, |
| |
| attention: function (){ |
| // NOTE: transitionEnd with keyframes causes odd behaviour |
| |
| if (this.options.attentionAnimation){ |
| this.$element |
| .removeClass('animated') |
| .removeClass(this.options.attentionAnimation); |
| |
| var that = this; |
| |
| setTimeout(function () { |
| that.$element |
| .addClass('animated') |
| .addClass(that.options.attentionAnimation); |
| }, 0); |
| } |
| |
| |
| this.focus(); |
| }, |
| |
| |
| destroy: function () { |
| var e = $.Event('destroy'); |
| this.$element.trigger(e); |
| if (e.isDefaultPrevented()) return; |
| |
| this.teardown(); |
| }, |
| |
| teardown: function () { |
| if (!this.$parent.length){ |
| this.$element.remove(); |
| this.$element = null; |
| return; |
| } |
| |
| if (this.$parent !== this.$element.parent()){ |
| this.$element.appendTo(this.$parent); |
| } |
| |
| this.$element.off('.modal'); |
| this.$element.removeData('modal'); |
| this.$element |
| .removeClass('in') |
| .attr('aria-hidden', true); |
| } |
| }; |
| |
| |
| /* MODAL PLUGIN DEFINITION |
| * ======================= */ |
| |
| $.fn.modal = function (option, args) { |
| return this.each(function () { |
| var $this = $(this), |
| data = $this.data('modal'), |
| options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option); |
| |
| if (!data) $this.data('modal', (data = new Modal(this, options))); |
| if (typeof option == 'string') data[option].apply(data, [].concat(args)); |
| else if (options.show) data.show() |
| }) |
| }; |
| |
| $.fn.modal.defaults = { |
| keyboard: true, |
| backdrop: true, |
| loading: false, |
| show: true, |
| width: null, |
| height: null, |
| maxHeight: null, |
| modalOverflow: false, |
| consumeTab: true, |
| focusOn: null, |
| replace: false, |
| resize: false, |
| attentionAnimation: 'shake', |
| manager: 'body', |
| spinner: '<div class="loading-spinner" style="width: 200px; margin-left: -100px;"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>' |
| }; |
| |
| $.fn.modal.Constructor = Modal; |
| |
| |
| /* MODAL DATA-API |
| * ============== */ |
| |
| $(function () { |
| $(document).off('click.modal').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) { |
| var $this = $(this), |
| href = $this.attr('href'), |
| $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))), //strip for ie7 |
| option = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()); |
| |
| e.preventDefault(); |
| $target |
| .modal(option) |
| .one('hide', function () { |
| $this.focus(); |
| }) |
| }); |
| }); |
| |
| }(window.jQuery); |