js/bootstrap-modal.js
author indvd00m (gotoindvdum[at]gmail[dot]com)
Fri, 04 Jul 2014 16:42:41 +0400
changeset 0 ba8ab09f730e
permissions -rw-r--r--
First home page
     1 /* =========================================================
     2  * bootstrap-modal.js v2.3.1
     3  * http://twitter.github.com/bootstrap/javascript.html#modals
     4  * =========================================================
     5  * Copyright 2012 Twitter, Inc.
     6  *
     7  * Licensed under the Apache License, Version 2.0 (the "License");
     8  * you may not use this file except in compliance with the License.
     9  * You may obtain a copy of the License at
    10  *
    11  * http://www.apache.org/licenses/LICENSE-2.0
    12  *
    13  * Unless required by applicable law or agreed to in writing, software
    14  * distributed under the License is distributed on an "AS IS" BASIS,
    15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  * See the License for the specific language governing permissions and
    17  * limitations under the License.
    18  * ========================================================= */
    19 
    20 
    21 !function ($) {
    22 
    23   "use strict"; // jshint ;_;
    24 
    25 
    26  /* MODAL CLASS DEFINITION
    27   * ====================== */
    28 
    29   var Modal = function (element, options) {
    30     this.options = options
    31     this.$element = $(element)
    32       .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
    33     this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
    34   }
    35 
    36   Modal.prototype = {
    37 
    38       constructor: Modal
    39 
    40     , toggle: function () {
    41         return this[!this.isShown ? 'show' : 'hide']()
    42       }
    43 
    44     , show: function () {
    45         var that = this
    46           , e = $.Event('show')
    47 
    48         this.$element.trigger(e)
    49 
    50         if (this.isShown || e.isDefaultPrevented()) return
    51 
    52         this.isShown = true
    53 
    54         this.escape()
    55 
    56         this.backdrop(function () {
    57           var transition = $.support.transition && that.$element.hasClass('fade')
    58 
    59           if (!that.$element.parent().length) {
    60             that.$element.appendTo(document.body) //don't move modals dom position
    61           }
    62 
    63           that.$element.show()
    64 
    65           if (transition) {
    66             that.$element[0].offsetWidth // force reflow
    67           }
    68 
    69           that.$element
    70             .addClass('in')
    71             .attr('aria-hidden', false)
    72 
    73           that.enforceFocus()
    74 
    75           transition ?
    76             that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
    77             that.$element.focus().trigger('shown')
    78 
    79         })
    80       }
    81 
    82     , hide: function (e) {
    83         e && e.preventDefault()
    84 
    85         var that = this
    86 
    87         e = $.Event('hide')
    88 
    89         this.$element.trigger(e)
    90 
    91         if (!this.isShown || e.isDefaultPrevented()) return
    92 
    93         this.isShown = false
    94 
    95         this.escape()
    96 
    97         $(document).off('focusin.modal')
    98 
    99         this.$element
   100           .removeClass('in')
   101           .attr('aria-hidden', true)
   102 
   103         $.support.transition && this.$element.hasClass('fade') ?
   104           this.hideWithTransition() :
   105           this.hideModal()
   106       }
   107 
   108     , enforceFocus: function () {
   109         var that = this
   110         $(document).on('focusin.modal', function (e) {
   111           if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
   112             that.$element.focus()
   113           }
   114         })
   115       }
   116 
   117     , escape: function () {
   118         var that = this
   119         if (this.isShown && this.options.keyboard) {
   120           this.$element.on('keyup.dismiss.modal', function ( e ) {
   121             e.which == 27 && that.hide()
   122           })
   123         } else if (!this.isShown) {
   124           this.$element.off('keyup.dismiss.modal')
   125         }
   126       }
   127 
   128     , hideWithTransition: function () {
   129         var that = this
   130           , timeout = setTimeout(function () {
   131               that.$element.off($.support.transition.end)
   132               that.hideModal()
   133             }, 500)
   134 
   135         this.$element.one($.support.transition.end, function () {
   136           clearTimeout(timeout)
   137           that.hideModal()
   138         })
   139       }
   140 
   141     , hideModal: function () {
   142         var that = this
   143         this.$element.hide()
   144         this.backdrop(function () {
   145           that.removeBackdrop()
   146           that.$element.trigger('hidden')
   147         })
   148       }
   149 
   150     , removeBackdrop: function () {
   151         this.$backdrop && this.$backdrop.remove()
   152         this.$backdrop = null
   153       }
   154 
   155     , backdrop: function (callback) {
   156         var that = this
   157           , animate = this.$element.hasClass('fade') ? 'fade' : ''
   158 
   159         if (this.isShown && this.options.backdrop) {
   160           var doAnimate = $.support.transition && animate
   161 
   162           this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
   163             .appendTo(document.body)
   164 
   165           this.$backdrop.click(
   166             this.options.backdrop == 'static' ?
   167               $.proxy(this.$element[0].focus, this.$element[0])
   168             : $.proxy(this.hide, this)
   169           )
   170 
   171           if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
   172 
   173           this.$backdrop.addClass('in')
   174 
   175           if (!callback) return
   176 
   177           doAnimate ?
   178             this.$backdrop.one($.support.transition.end, callback) :
   179             callback()
   180 
   181         } else if (!this.isShown && this.$backdrop) {
   182           this.$backdrop.removeClass('in')
   183 
   184           $.support.transition && this.$element.hasClass('fade')?
   185             this.$backdrop.one($.support.transition.end, callback) :
   186             callback()
   187 
   188         } else if (callback) {
   189           callback()
   190         }
   191       }
   192   }
   193 
   194 
   195  /* MODAL PLUGIN DEFINITION
   196   * ======================= */
   197 
   198   var old = $.fn.modal
   199 
   200   $.fn.modal = function (option) {
   201     return this.each(function () {
   202       var $this = $(this)
   203         , data = $this.data('modal')
   204         , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
   205       if (!data) $this.data('modal', (data = new Modal(this, options)))
   206       if (typeof option == 'string') data[option]()
   207       else if (options.show) data.show()
   208     })
   209   }
   210 
   211   $.fn.modal.defaults = {
   212       backdrop: true
   213     , keyboard: true
   214     , show: true
   215   }
   216 
   217   $.fn.modal.Constructor = Modal
   218 
   219 
   220  /* MODAL NO CONFLICT
   221   * ================= */
   222 
   223   $.fn.modal.noConflict = function () {
   224     $.fn.modal = old
   225     return this
   226   }
   227 
   228 
   229  /* MODAL DATA-API
   230   * ============== */
   231 
   232   $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
   233     var $this = $(this)
   234       , href = $this.attr('href')
   235       , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
   236       , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
   237 
   238     e.preventDefault()
   239 
   240     $target
   241       .modal(option)
   242       .one('hide', function () {
   243         $this.focus()
   244       })
   245   })
   246 
   247 }(window.jQuery);