problem_child 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.bowerrc +3 -0
  3. data/.gitignore +10 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/Procfile +1 -0
  7. data/README.md +53 -0
  8. data/Rakefile +8 -0
  9. data/bower.json +13 -0
  10. data/config.ru +3 -0
  11. data/lib/problem_child.rb +126 -0
  12. data/lib/problem_child/public/vendor/bootstrap/.bower.json +47 -0
  13. data/lib/problem_child/public/vendor/bootstrap/Gruntfile.js +472 -0
  14. data/lib/problem_child/public/vendor/bootstrap/LICENSE +21 -0
  15. data/lib/problem_child/public/vendor/bootstrap/README.md +129 -0
  16. data/lib/problem_child/public/vendor/bootstrap/bower.json +38 -0
  17. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap-theme.css +470 -0
  18. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap-theme.css.map +1 -0
  19. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap-theme.min.css +5 -0
  20. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap.css +6332 -0
  21. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap.css.map +1 -0
  22. data/lib/problem_child/public/vendor/bootstrap/dist/css/bootstrap.min.css +5 -0
  23. data/lib/problem_child/public/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
  24. data/lib/problem_child/public/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +229 -0
  25. data/lib/problem_child/public/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  26. data/lib/problem_child/public/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
  27. data/lib/problem_child/public/vendor/bootstrap/dist/js/bootstrap.js +2320 -0
  28. data/lib/problem_child/public/vendor/bootstrap/dist/js/bootstrap.min.js +7 -0
  29. data/lib/problem_child/public/vendor/bootstrap/dist/js/npm.js +13 -0
  30. data/lib/problem_child/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  31. data/lib/problem_child/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg +229 -0
  32. data/lib/problem_child/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  33. data/lib/problem_child/public/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  34. data/lib/problem_child/public/vendor/bootstrap/js/.jscsrc +34 -0
  35. data/lib/problem_child/public/vendor/bootstrap/js/.jshintrc +15 -0
  36. data/lib/problem_child/public/vendor/bootstrap/js/affix.js +162 -0
  37. data/lib/problem_child/public/vendor/bootstrap/js/alert.js +94 -0
  38. data/lib/problem_child/public/vendor/bootstrap/js/button.js +116 -0
  39. data/lib/problem_child/public/vendor/bootstrap/js/carousel.js +240 -0
  40. data/lib/problem_child/public/vendor/bootstrap/js/collapse.js +211 -0
  41. data/lib/problem_child/public/vendor/bootstrap/js/dropdown.js +161 -0
  42. data/lib/problem_child/public/vendor/bootstrap/js/modal.js +324 -0
  43. data/lib/problem_child/public/vendor/bootstrap/js/popover.js +119 -0
  44. data/lib/problem_child/public/vendor/bootstrap/js/scrollspy.js +175 -0
  45. data/lib/problem_child/public/vendor/bootstrap/js/tab.js +153 -0
  46. data/lib/problem_child/public/vendor/bootstrap/js/tooltip.js +478 -0
  47. data/lib/problem_child/public/vendor/bootstrap/js/transition.js +59 -0
  48. data/lib/problem_child/public/vendor/bootstrap/package.json +82 -0
  49. data/lib/problem_child/public/vendor/jquery/.bower.json +37 -0
  50. data/lib/problem_child/public/vendor/jquery/MIT-LICENSE.txt +21 -0
  51. data/lib/problem_child/public/vendor/jquery/bower.json +27 -0
  52. data/lib/problem_child/public/vendor/jquery/dist/jquery.js +9205 -0
  53. data/lib/problem_child/public/vendor/jquery/dist/jquery.min.js +5 -0
  54. data/lib/problem_child/public/vendor/jquery/dist/jquery.min.map +1 -0
  55. data/lib/problem_child/version.rb +3 -0
  56. data/lib/problem_child/views/form.erb +22 -0
  57. data/lib/problem_child/views/layout.erb +27 -0
  58. data/problem_child.gemspec +32 -0
  59. data/script/bootstrap +1 -0
  60. data/script/console +1 -0
  61. data/script/release +38 -0
  62. data/script/server +1 -0
  63. metadata +260 -0
@@ -0,0 +1,211 @@
1
+ /* ========================================================================
2
+ * Bootstrap: collapse.js v3.3.1
3
+ * http://getbootstrap.com/javascript/#collapse
4
+ * ========================================================================
5
+ * Copyright 2011-2014 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // COLLAPSE PUBLIC CLASS DEFINITION
14
+ // ================================
15
+
16
+ var Collapse = function (element, options) {
17
+ this.$element = $(element)
18
+ this.options = $.extend({}, Collapse.DEFAULTS, options)
19
+ this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
20
+ this.transitioning = null
21
+
22
+ if (this.options.parent) {
23
+ this.$parent = this.getParent()
24
+ } else {
25
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
26
+ }
27
+
28
+ if (this.options.toggle) this.toggle()
29
+ }
30
+
31
+ Collapse.VERSION = '3.3.1'
32
+
33
+ Collapse.TRANSITION_DURATION = 350
34
+
35
+ Collapse.DEFAULTS = {
36
+ toggle: true,
37
+ trigger: '[data-toggle="collapse"]'
38
+ }
39
+
40
+ Collapse.prototype.dimension = function () {
41
+ var hasWidth = this.$element.hasClass('width')
42
+ return hasWidth ? 'width' : 'height'
43
+ }
44
+
45
+ Collapse.prototype.show = function () {
46
+ if (this.transitioning || this.$element.hasClass('in')) return
47
+
48
+ var activesData
49
+ var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing')
50
+
51
+ if (actives && actives.length) {
52
+ activesData = actives.data('bs.collapse')
53
+ if (activesData && activesData.transitioning) return
54
+ }
55
+
56
+ var startEvent = $.Event('show.bs.collapse')
57
+ this.$element.trigger(startEvent)
58
+ if (startEvent.isDefaultPrevented()) return
59
+
60
+ if (actives && actives.length) {
61
+ Plugin.call(actives, 'hide')
62
+ activesData || actives.data('bs.collapse', null)
63
+ }
64
+
65
+ var dimension = this.dimension()
66
+
67
+ this.$element
68
+ .removeClass('collapse')
69
+ .addClass('collapsing')[dimension](0)
70
+ .attr('aria-expanded', true)
71
+
72
+ this.$trigger
73
+ .removeClass('collapsed')
74
+ .attr('aria-expanded', true)
75
+
76
+ this.transitioning = 1
77
+
78
+ var complete = function () {
79
+ this.$element
80
+ .removeClass('collapsing')
81
+ .addClass('collapse in')[dimension]('')
82
+ this.transitioning = 0
83
+ this.$element
84
+ .trigger('shown.bs.collapse')
85
+ }
86
+
87
+ if (!$.support.transition) return complete.call(this)
88
+
89
+ var scrollSize = $.camelCase(['scroll', dimension].join('-'))
90
+
91
+ this.$element
92
+ .one('bsTransitionEnd', $.proxy(complete, this))
93
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
94
+ }
95
+
96
+ Collapse.prototype.hide = function () {
97
+ if (this.transitioning || !this.$element.hasClass('in')) return
98
+
99
+ var startEvent = $.Event('hide.bs.collapse')
100
+ this.$element.trigger(startEvent)
101
+ if (startEvent.isDefaultPrevented()) return
102
+
103
+ var dimension = this.dimension()
104
+
105
+ this.$element[dimension](this.$element[dimension]())[0].offsetHeight
106
+
107
+ this.$element
108
+ .addClass('collapsing')
109
+ .removeClass('collapse in')
110
+ .attr('aria-expanded', false)
111
+
112
+ this.$trigger
113
+ .addClass('collapsed')
114
+ .attr('aria-expanded', false)
115
+
116
+ this.transitioning = 1
117
+
118
+ var complete = function () {
119
+ this.transitioning = 0
120
+ this.$element
121
+ .removeClass('collapsing')
122
+ .addClass('collapse')
123
+ .trigger('hidden.bs.collapse')
124
+ }
125
+
126
+ if (!$.support.transition) return complete.call(this)
127
+
128
+ this.$element
129
+ [dimension](0)
130
+ .one('bsTransitionEnd', $.proxy(complete, this))
131
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
132
+ }
133
+
134
+ Collapse.prototype.toggle = function () {
135
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
136
+ }
137
+
138
+ Collapse.prototype.getParent = function () {
139
+ return $(this.options.parent)
140
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
141
+ .each($.proxy(function (i, element) {
142
+ var $element = $(element)
143
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
144
+ }, this))
145
+ .end()
146
+ }
147
+
148
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
149
+ var isOpen = $element.hasClass('in')
150
+
151
+ $element.attr('aria-expanded', isOpen)
152
+ $trigger
153
+ .toggleClass('collapsed', !isOpen)
154
+ .attr('aria-expanded', isOpen)
155
+ }
156
+
157
+ function getTargetFromTrigger($trigger) {
158
+ var href
159
+ var target = $trigger.attr('data-target')
160
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
161
+
162
+ return $(target)
163
+ }
164
+
165
+
166
+ // COLLAPSE PLUGIN DEFINITION
167
+ // ==========================
168
+
169
+ function Plugin(option) {
170
+ return this.each(function () {
171
+ var $this = $(this)
172
+ var data = $this.data('bs.collapse')
173
+ var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
174
+
175
+ if (!data && options.toggle && option == 'show') options.toggle = false
176
+ if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
177
+ if (typeof option == 'string') data[option]()
178
+ })
179
+ }
180
+
181
+ var old = $.fn.collapse
182
+
183
+ $.fn.collapse = Plugin
184
+ $.fn.collapse.Constructor = Collapse
185
+
186
+
187
+ // COLLAPSE NO CONFLICT
188
+ // ====================
189
+
190
+ $.fn.collapse.noConflict = function () {
191
+ $.fn.collapse = old
192
+ return this
193
+ }
194
+
195
+
196
+ // COLLAPSE DATA-API
197
+ // =================
198
+
199
+ $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
200
+ var $this = $(this)
201
+
202
+ if (!$this.attr('data-target')) e.preventDefault()
203
+
204
+ var $target = getTargetFromTrigger($this)
205
+ var data = $target.data('bs.collapse')
206
+ var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
207
+
208
+ Plugin.call($target, option)
209
+ })
210
+
211
+ }(jQuery);
@@ -0,0 +1,161 @@
1
+ /* ========================================================================
2
+ * Bootstrap: dropdown.js v3.3.1
3
+ * http://getbootstrap.com/javascript/#dropdowns
4
+ * ========================================================================
5
+ * Copyright 2011-2014 Twitter, Inc.
6
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
+ * ======================================================================== */
8
+
9
+
10
+ +function ($) {
11
+ 'use strict';
12
+
13
+ // DROPDOWN CLASS DEFINITION
14
+ // =========================
15
+
16
+ var backdrop = '.dropdown-backdrop'
17
+ var toggle = '[data-toggle="dropdown"]'
18
+ var Dropdown = function (element) {
19
+ $(element).on('click.bs.dropdown', this.toggle)
20
+ }
21
+
22
+ Dropdown.VERSION = '3.3.1'
23
+
24
+ Dropdown.prototype.toggle = function (e) {
25
+ var $this = $(this)
26
+
27
+ if ($this.is('.disabled, :disabled')) return
28
+
29
+ var $parent = getParent($this)
30
+ var isActive = $parent.hasClass('open')
31
+
32
+ clearMenus()
33
+
34
+ if (!isActive) {
35
+ if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
36
+ // if mobile we use a backdrop because click events don't delegate
37
+ $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
38
+ }
39
+
40
+ var relatedTarget = { relatedTarget: this }
41
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
42
+
43
+ if (e.isDefaultPrevented()) return
44
+
45
+ $this
46
+ .trigger('focus')
47
+ .attr('aria-expanded', 'true')
48
+
49
+ $parent
50
+ .toggleClass('open')
51
+ .trigger('shown.bs.dropdown', relatedTarget)
52
+ }
53
+
54
+ return false
55
+ }
56
+
57
+ Dropdown.prototype.keydown = function (e) {
58
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
59
+
60
+ var $this = $(this)
61
+
62
+ e.preventDefault()
63
+ e.stopPropagation()
64
+
65
+ if ($this.is('.disabled, :disabled')) return
66
+
67
+ var $parent = getParent($this)
68
+ var isActive = $parent.hasClass('open')
69
+
70
+ if ((!isActive && e.which != 27) || (isActive && e.which == 27)) {
71
+ if (e.which == 27) $parent.find(toggle).trigger('focus')
72
+ return $this.trigger('click')
73
+ }
74
+
75
+ var desc = ' li:not(.divider):visible a'
76
+ var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
77
+
78
+ if (!$items.length) return
79
+
80
+ var index = $items.index(e.target)
81
+
82
+ if (e.which == 38 && index > 0) index-- // up
83
+ if (e.which == 40 && index < $items.length - 1) index++ // down
84
+ if (!~index) index = 0
85
+
86
+ $items.eq(index).trigger('focus')
87
+ }
88
+
89
+ function clearMenus(e) {
90
+ if (e && e.which === 3) return
91
+ $(backdrop).remove()
92
+ $(toggle).each(function () {
93
+ var $this = $(this)
94
+ var $parent = getParent($this)
95
+ var relatedTarget = { relatedTarget: this }
96
+
97
+ if (!$parent.hasClass('open')) return
98
+
99
+ $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
100
+
101
+ if (e.isDefaultPrevented()) return
102
+
103
+ $this.attr('aria-expanded', 'false')
104
+ $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
105
+ })
106
+ }
107
+
108
+ function getParent($this) {
109
+ var selector = $this.attr('data-target')
110
+
111
+ if (!selector) {
112
+ selector = $this.attr('href')
113
+ selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
114
+ }
115
+
116
+ var $parent = selector && $(selector)
117
+
118
+ return $parent && $parent.length ? $parent : $this.parent()
119
+ }
120
+
121
+
122
+ // DROPDOWN PLUGIN DEFINITION
123
+ // ==========================
124
+
125
+ function Plugin(option) {
126
+ return this.each(function () {
127
+ var $this = $(this)
128
+ var data = $this.data('bs.dropdown')
129
+
130
+ if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
131
+ if (typeof option == 'string') data[option].call($this)
132
+ })
133
+ }
134
+
135
+ var old = $.fn.dropdown
136
+
137
+ $.fn.dropdown = Plugin
138
+ $.fn.dropdown.Constructor = Dropdown
139
+
140
+
141
+ // DROPDOWN NO CONFLICT
142
+ // ====================
143
+
144
+ $.fn.dropdown.noConflict = function () {
145
+ $.fn.dropdown = old
146
+ return this
147
+ }
148
+
149
+
150
+ // APPLY TO STANDARD DROPDOWN ELEMENTS
151
+ // ===================================
152
+
153
+ $(document)
154
+ .on('click.bs.dropdown.data-api', clearMenus)
155
+ .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
156
+ .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
157
+ .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
158
+ .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
159
+ .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
160
+
161
+ }(jQuery);
@@ -0,0 +1,324 @@
1
+ /* ========================================================================
2
+ * Bootstrap: modal.js v3.3.1
3
+ * http://getbootstrap.com/javascript/#modals
4
+ * ========================================================================
5
+ * Copyright 2011-2014 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.1'
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);