bootstrap-modal.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. !function ($) {
  20. "use strict"; // jshint ;_;
  21. /* MODAL CLASS DEFINITION
  22. * ====================== */
  23. var Modal = function (element, options) {
  24. this.options = options
  25. this.$element = $(element)
  26. .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
  27. this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
  28. }
  29. Modal.prototype = {
  30. constructor: Modal
  31. , toggle: function () {
  32. return this[!this.isShown ? 'show' : 'hide']()
  33. }
  34. , show: function () {
  35. var that = this
  36. , e = $.Event('show')
  37. this.$element.trigger(e)
  38. if (this.isShown || e.isDefaultPrevented()) return
  39. this.isShown = true
  40. this.escape()
  41. this.backdrop(function () {
  42. var transition = $.support.transition && that.$element.hasClass('fade')
  43. if (!that.$element.parent().length) {
  44. that.$element.appendTo(document.body) //don't move modals dom position
  45. }
  46. that.$element.show()
  47. if (transition) {
  48. that.$element[0].offsetWidth // force reflow
  49. }
  50. that.$element
  51. .addClass('in')
  52. .attr('aria-hidden', false)
  53. that.enforceFocus()
  54. transition ?
  55. that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
  56. that.$element.focus().trigger('shown')
  57. })
  58. }
  59. , hide: function (e) {
  60. e && e.preventDefault()
  61. var that = this
  62. e = $.Event('hide')
  63. this.$element.trigger(e)
  64. if (!this.isShown || e.isDefaultPrevented()) return
  65. this.isShown = false
  66. this.escape()
  67. $(document).off('focusin.modal')
  68. this.$element
  69. .removeClass('in')
  70. .attr('aria-hidden', true)
  71. $.support.transition && this.$element.hasClass('fade') ?
  72. this.hideWithTransition() :
  73. this.hideModal()
  74. }
  75. , enforceFocus: function () {
  76. var that = this
  77. $(document).on('focusin.modal', function (e) {
  78. if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
  79. that.$element.focus()
  80. }
  81. })
  82. }
  83. , escape: function () {
  84. var that = this
  85. if (this.isShown && this.options.keyboard) {
  86. this.$element.on('keyup.dismiss.modal', function ( e ) {
  87. e.which == 27 && that.hide()
  88. })
  89. } else if (!this.isShown) {
  90. this.$element.off('keyup.dismiss.modal')
  91. }
  92. }
  93. , hideWithTransition: function () {
  94. var that = this
  95. , timeout = setTimeout(function () {
  96. that.$element.off($.support.transition.end)
  97. that.hideModal()
  98. }, 500)
  99. this.$element.one($.support.transition.end, function () {
  100. clearTimeout(timeout)
  101. that.hideModal()
  102. })
  103. }
  104. , hideModal: function () {
  105. var that = this
  106. this.$element.hide()
  107. this.backdrop(function () {
  108. that.removeBackdrop()
  109. that.$element.trigger('hidden')
  110. })
  111. }
  112. , removeBackdrop: function () {
  113. this.$backdrop && this.$backdrop.remove()
  114. this.$backdrop = null
  115. }
  116. , backdrop: function (callback) {
  117. var that = this
  118. , animate = this.$element.hasClass('fade') ? 'fade' : ''
  119. if (this.isShown && this.options.backdrop) {
  120. var doAnimate = $.support.transition && animate
  121. this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
  122. .appendTo(document.body)
  123. this.$backdrop.click(
  124. this.options.backdrop == 'static' ?
  125. $.proxy(this.$element[0].focus, this.$element[0])
  126. : $.proxy(this.hide, this)
  127. )
  128. if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
  129. this.$backdrop.addClass('in')
  130. if (!callback) return
  131. doAnimate ?
  132. this.$backdrop.one($.support.transition.end, callback) :
  133. callback()
  134. } else if (!this.isShown && this.$backdrop) {
  135. this.$backdrop.removeClass('in')
  136. $.support.transition && this.$element.hasClass('fade')?
  137. this.$backdrop.one($.support.transition.end, callback) :
  138. callback()
  139. } else if (callback) {
  140. callback()
  141. }
  142. }
  143. }
  144. /* MODAL PLUGIN DEFINITION
  145. * ======================= */
  146. var old = $.fn.modal
  147. $.fn.modal = function (option) {
  148. return this.each(function () {
  149. var $this = $(this)
  150. , data = $this.data('modal')
  151. , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
  152. if (!data) $this.data('modal', (data = new Modal(this, options)))
  153. if (typeof option == 'string') data[option]()
  154. else if (options.show) data.show()
  155. })
  156. }
  157. $.fn.modal.defaults = {
  158. backdrop: true
  159. , keyboard: true
  160. , show: true
  161. }
  162. $.fn.modal.Constructor = Modal
  163. /* MODAL NO CONFLICT
  164. * ================= */
  165. $.fn.modal.noConflict = function () {
  166. $.fn.modal = old
  167. return this
  168. }
  169. /* MODAL DATA-API
  170. * ============== */
  171. $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
  172. var $this = $(this)
  173. , href = $this.attr('href')
  174. , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
  175. , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
  176. e.preventDefault()
  177. $target
  178. .modal(option)
  179. .one('hide', function () {
  180. $this.focus()
  181. })
  182. })
  183. }(window.jQuery);