Merge "add web portal framework for TestAPI"
[releng.git] / utils / test / testapi / 3rd_party / static / testapi-ui / assets / lib / bootstrap / js / modal.js
1 /* ========================================================================
2  * Bootstrap: modal.js v3.3.2
3  * http://getbootstrap.com/javascript/#modals
4  * ========================================================================
5  * Copyright 2011-2015 Twitter, Inc.
6  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7  * ======================================================================== */
8
9
10 +function ($) {
11   'use strict';
12
13   // MODAL CLASS DEFINITION
14   // ======================
15
16   var Modal = function (element, options) {
17     this.options        = options
18     this.$body          = $(document.body)
19     this.$element       = $(element)
20     this.$backdrop      =
21     this.isShown        = null
22     this.scrollbarWidth = 0
23
24     if (this.options.remote) {
25       this.$element
26         .find('.modal-content')
27         .load(this.options.remote, $.proxy(function () {
28           this.$element.trigger('loaded.bs.modal')
29         }, this))
30     }
31   }
32
33   Modal.VERSION  = '3.3.2'
34
35   Modal.TRANSITION_DURATION = 300
36   Modal.BACKDROP_TRANSITION_DURATION = 150
37
38   Modal.DEFAULTS = {
39     backdrop: true,
40     keyboard: true,
41     show: true
42   }
43
44   Modal.prototype.toggle = function (_relatedTarget) {
45     return this.isShown ? this.hide() : this.show(_relatedTarget)
46   }
47
48   Modal.prototype.show = function (_relatedTarget) {
49     var that = this
50     var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
51
52     this.$element.trigger(e)
53
54     if (this.isShown || e.isDefaultPrevented()) return
55
56     this.isShown = true
57
58     this.checkScrollbar()
59     this.setScrollbar()
60     this.$body.addClass('modal-open')
61
62     this.escape()
63     this.resize()
64
65     this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
66
67     this.backdrop(function () {
68       var transition = $.support.transition && that.$element.hasClass('fade')
69
70       if (!that.$element.parent().length) {
71         that.$element.appendTo(that.$body) // don't move modals dom position
72       }
73
74       that.$element
75         .show()
76         .scrollTop(0)
77
78       if (that.options.backdrop) that.adjustBackdrop()
79       that.adjustDialog()
80
81       if (transition) {
82         that.$element[0].offsetWidth // force reflow
83       }
84
85       that.$element
86         .addClass('in')
87         .attr('aria-hidden', false)
88
89       that.enforceFocus()
90
91       var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
92
93       transition ?
94         that.$element.find('.modal-dialog') // wait for modal to slide in
95           .one('bsTransitionEnd', function () {
96             that.$element.trigger('focus').trigger(e)
97           })
98           .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
99         that.$element.trigger('focus').trigger(e)
100     })
101   }
102
103   Modal.prototype.hide = function (e) {
104     if (e) e.preventDefault()
105
106     e = $.Event('hide.bs.modal')
107
108     this.$element.trigger(e)
109
110     if (!this.isShown || e.isDefaultPrevented()) return
111
112     this.isShown = false
113
114     this.escape()
115     this.resize()
116
117     $(document).off('focusin.bs.modal')
118
119     this.$element
120       .removeClass('in')
121       .attr('aria-hidden', true)
122       .off('click.dismiss.bs.modal')
123
124     $.support.transition && this.$element.hasClass('fade') ?
125       this.$element
126         .one('bsTransitionEnd', $.proxy(this.hideModal, this))
127         .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
128       this.hideModal()
129   }
130
131   Modal.prototype.enforceFocus = function () {
132     $(document)
133       .off('focusin.bs.modal') // guard against infinite focus loop
134       .on('focusin.bs.modal', $.proxy(function (e) {
135         if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
136           this.$element.trigger('focus')
137         }
138       }, this))
139   }
140
141   Modal.prototype.escape = function () {
142     if (this.isShown && this.options.keyboard) {
143       this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
144         e.which == 27 && this.hide()
145       }, this))
146     } else if (!this.isShown) {
147       this.$element.off('keydown.dismiss.bs.modal')
148     }
149   }
150
151   Modal.prototype.resize = function () {
152     if (this.isShown) {
153       $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
154     } else {
155       $(window).off('resize.bs.modal')
156     }
157   }
158
159   Modal.prototype.hideModal = function () {
160     var that = this
161     this.$element.hide()
162     this.backdrop(function () {
163       that.$body.removeClass('modal-open')
164       that.resetAdjustments()
165       that.resetScrollbar()
166       that.$element.trigger('hidden.bs.modal')
167     })
168   }
169
170   Modal.prototype.removeBackdrop = function () {
171     this.$backdrop && this.$backdrop.remove()
172     this.$backdrop = null
173   }
174
175   Modal.prototype.backdrop = function (callback) {
176     var that = this
177     var animate = this.$element.hasClass('fade') ? 'fade' : ''
178
179     if (this.isShown && this.options.backdrop) {
180       var doAnimate = $.support.transition && animate
181
182       this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
183         .prependTo(this.$element)
184         .on('click.dismiss.bs.modal', $.proxy(function (e) {
185           if (e.target !== e.currentTarget) return
186           this.options.backdrop == 'static'
187             ? this.$element[0].focus.call(this.$element[0])
188             : this.hide.call(this)
189         }, this))
190
191       if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
192
193       this.$backdrop.addClass('in')
194
195       if (!callback) return
196
197       doAnimate ?
198         this.$backdrop
199           .one('bsTransitionEnd', callback)
200           .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
201         callback()
202
203     } else if (!this.isShown && this.$backdrop) {
204       this.$backdrop.removeClass('in')
205
206       var callbackRemove = function () {
207         that.removeBackdrop()
208         callback && callback()
209       }
210       $.support.transition && this.$element.hasClass('fade') ?
211         this.$backdrop
212           .one('bsTransitionEnd', callbackRemove)
213           .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
214         callbackRemove()
215
216     } else if (callback) {
217       callback()
218     }
219   }
220
221   // these following methods are used to handle overflowing modals
222
223   Modal.prototype.handleUpdate = function () {
224     if (this.options.backdrop) this.adjustBackdrop()
225     this.adjustDialog()
226   }
227
228   Modal.prototype.adjustBackdrop = function () {
229     this.$backdrop
230       .css('height', 0)
231       .css('height', this.$element[0].scrollHeight)
232   }
233
234   Modal.prototype.adjustDialog = function () {
235     var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
236
237     this.$element.css({
238       paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
239       paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
240     })
241   }
242
243   Modal.prototype.resetAdjustments = function () {
244     this.$element.css({
245       paddingLeft: '',
246       paddingRight: ''
247     })
248   }
249
250   Modal.prototype.checkScrollbar = function () {
251     this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
252     this.scrollbarWidth = this.measureScrollbar()
253   }
254
255   Modal.prototype.setScrollbar = function () {
256     var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
257     if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
258   }
259
260   Modal.prototype.resetScrollbar = function () {
261     this.$body.css('padding-right', '')
262   }
263
264   Modal.prototype.measureScrollbar = function () { // thx walsh
265     var scrollDiv = document.createElement('div')
266     scrollDiv.className = 'modal-scrollbar-measure'
267     this.$body.append(scrollDiv)
268     var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
269     this.$body[0].removeChild(scrollDiv)
270     return scrollbarWidth
271   }
272
273
274   // MODAL PLUGIN DEFINITION
275   // =======================
276
277   function Plugin(option, _relatedTarget) {
278     return this.each(function () {
279       var $this   = $(this)
280       var data    = $this.data('bs.modal')
281       var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
282
283       if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
284       if (typeof option == 'string') data[option](_relatedTarget)
285       else if (options.show) data.show(_relatedTarget)
286     })
287   }
288
289   var old = $.fn.modal
290
291   $.fn.modal             = Plugin
292   $.fn.modal.Constructor = Modal
293
294
295   // MODAL NO CONFLICT
296   // =================
297
298   $.fn.modal.noConflict = function () {
299     $.fn.modal = old
300     return this
301   }
302
303
304   // MODAL DATA-API
305   // ==============
306
307   $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
308     var $this   = $(this)
309     var href    = $this.attr('href')
310     var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
311     var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
312
313     if ($this.is('a')) e.preventDefault()
314
315     $target.one('show.bs.modal', function (showEvent) {
316       if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
317       $target.one('hidden.bs.modal', function () {
318         $this.is(':visible') && $this.trigger('focus')
319       })
320     })
321     Plugin.call($target, option, this)
322   })
323
324 }(jQuery);