rails_admin 2.1.1 → 2.2.0
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.
Potentially problematic release.
This version of rails_admin might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/rails_admin/jquery.migrate.js +3 -0
- data/app/assets/javascripts/rails_admin/ra.filter-box.js +1 -4
- data/app/assets/javascripts/rails_admin/ra.nested-form-hooks.js +3 -3
- data/app/assets/javascripts/rails_admin/ra.widgets.js +1 -1
- data/app/assets/javascripts/rails_admin/rails_admin.js +2 -1
- data/app/assets/javascripts/rails_admin/ui.js +2 -2
- data/app/helpers/rails_admin/form_builder.rb +2 -0
- data/lib/rails_admin/extensions/paper_trail/auditing_adapter.rb +1 -1
- data/lib/rails_admin/version.rb +2 -2
- data/vendor/assets/javascripts/rails_admin/bootstrap-datetimepicker.js +317 -150
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-affix.js +50 -28
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-alert.js +10 -7
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-button.js +35 -20
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-carousel.js +48 -25
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-collapse.js +70 -28
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-dropdown.js +56 -42
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-modal.js +118 -40
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-popover.js +26 -16
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-scrollspy.js +29 -27
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tab.js +46 -19
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-tooltip.js +280 -60
- data/vendor/assets/javascripts/rails_admin/bootstrap/bootstrap-transition.js +5 -5
- data/vendor/assets/javascripts/rails_admin/jquery.pjax.js +317 -160
- data/vendor/assets/javascripts/rails_admin/moment-with-locales.js +11210 -9290
- metadata +3 -3
- data/config/initializers/devise_patch.rb +0 -9
@@ -1,8 +1,8 @@
|
|
1
1
|
/* ========================================================================
|
2
|
-
* Bootstrap: affix.js v3.
|
3
|
-
*
|
2
|
+
* Bootstrap: affix.js v3.4.1
|
3
|
+
* https://getbootstrap.com/docs/3.4/javascript/#affix
|
4
4
|
* ========================================================================
|
5
|
-
* Copyright 2011-
|
5
|
+
* Copyright 2011-2019 Twitter, Inc.
|
6
6
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
7
7
|
* ======================================================================== */
|
8
8
|
|
@@ -16,19 +16,21 @@
|
|
16
16
|
var Affix = function (element, options) {
|
17
17
|
this.options = $.extend({}, Affix.DEFAULTS, options)
|
18
18
|
|
19
|
-
|
19
|
+
var target = this.options.target === Affix.DEFAULTS.target ? $(this.options.target) : $(document).find(this.options.target)
|
20
|
+
|
21
|
+
this.$target = target
|
20
22
|
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
|
21
23
|
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
|
22
24
|
|
23
25
|
this.$element = $(element)
|
24
|
-
this.affixed =
|
25
|
-
this.unpin =
|
26
|
+
this.affixed = null
|
27
|
+
this.unpin = null
|
26
28
|
this.pinnedOffset = null
|
27
29
|
|
28
30
|
this.checkPosition()
|
29
31
|
}
|
30
32
|
|
31
|
-
Affix.VERSION = '3.
|
33
|
+
Affix.VERSION = '3.4.1'
|
32
34
|
|
33
35
|
Affix.RESET = 'affix affix-top affix-bottom'
|
34
36
|
|
@@ -37,6 +39,28 @@
|
|
37
39
|
target: window
|
38
40
|
}
|
39
41
|
|
42
|
+
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
|
43
|
+
var scrollTop = this.$target.scrollTop()
|
44
|
+
var position = this.$element.offset()
|
45
|
+
var targetHeight = this.$target.height()
|
46
|
+
|
47
|
+
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
|
48
|
+
|
49
|
+
if (this.affixed == 'bottom') {
|
50
|
+
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
|
51
|
+
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
|
52
|
+
}
|
53
|
+
|
54
|
+
var initializing = this.affixed == null
|
55
|
+
var colliderTop = initializing ? scrollTop : position.top
|
56
|
+
var colliderHeight = initializing ? targetHeight : height
|
57
|
+
|
58
|
+
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
|
59
|
+
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
|
60
|
+
|
61
|
+
return false
|
62
|
+
}
|
63
|
+
|
40
64
|
Affix.prototype.getPinnedOffset = function () {
|
41
65
|
if (this.pinnedOffset) return this.pinnedOffset
|
42
66
|
this.$element.removeClass(Affix.RESET).addClass('affix')
|
@@ -52,42 +76,40 @@
|
|
52
76
|
Affix.prototype.checkPosition = function () {
|
53
77
|
if (!this.$element.is(':visible')) return
|
54
78
|
|
55
|
-
var
|
56
|
-
var scrollTop = this.$target.scrollTop()
|
57
|
-
var position = this.$element.offset()
|
79
|
+
var height = this.$element.height()
|
58
80
|
var offset = this.options.offset
|
59
81
|
var offsetTop = offset.top
|
60
82
|
var offsetBottom = offset.bottom
|
83
|
+
var scrollHeight = Math.max($(document).height(), $(document.body).height())
|
61
84
|
|
62
85
|
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
63
86
|
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
|
64
87
|
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
|
65
88
|
|
66
|
-
var affix = this.
|
67
|
-
offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
|
68
|
-
offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
|
89
|
+
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
|
69
90
|
|
70
|
-
if (this.affixed
|
71
|
-
|
91
|
+
if (this.affixed != affix) {
|
92
|
+
if (this.unpin != null) this.$element.css('top', '')
|
72
93
|
|
73
|
-
|
74
|
-
|
94
|
+
var affixType = 'affix' + (affix ? '-' + affix : '')
|
95
|
+
var e = $.Event(affixType + '.bs.affix')
|
75
96
|
|
76
|
-
|
97
|
+
this.$element.trigger(e)
|
77
98
|
|
78
|
-
|
99
|
+
if (e.isDefaultPrevented()) return
|
79
100
|
|
80
|
-
|
81
|
-
|
101
|
+
this.affixed = affix
|
102
|
+
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
|
82
103
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
104
|
+
this.$element
|
105
|
+
.removeClass(Affix.RESET)
|
106
|
+
.addClass(affixType)
|
107
|
+
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
|
108
|
+
}
|
87
109
|
|
88
110
|
if (affix == 'bottom') {
|
89
111
|
this.$element.offset({
|
90
|
-
top: scrollHeight -
|
112
|
+
top: scrollHeight - height - offsetBottom
|
91
113
|
})
|
92
114
|
}
|
93
115
|
}
|
@@ -132,8 +154,8 @@
|
|
132
154
|
|
133
155
|
data.offset = data.offset || {}
|
134
156
|
|
135
|
-
if (data.offsetBottom) data.offset.bottom = data.offsetBottom
|
136
|
-
if (data.offsetTop)
|
157
|
+
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
|
158
|
+
if (data.offsetTop != null) data.offset.top = data.offsetTop
|
137
159
|
|
138
160
|
Plugin.call($spy, data)
|
139
161
|
})
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/* ========================================================================
|
2
|
-
* Bootstrap: alert.js v3.
|
3
|
-
*
|
2
|
+
* Bootstrap: alert.js v3.4.1
|
3
|
+
* https://getbootstrap.com/docs/3.4/javascript/#alerts
|
4
4
|
* ========================================================================
|
5
|
-
* Copyright 2011-
|
5
|
+
* Copyright 2011-2019 Twitter, Inc.
|
6
6
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
7
7
|
* ======================================================================== */
|
8
8
|
|
@@ -18,7 +18,9 @@
|
|
18
18
|
$(el).on('click', dismiss, this.close)
|
19
19
|
}
|
20
20
|
|
21
|
-
Alert.VERSION = '3.
|
21
|
+
Alert.VERSION = '3.4.1'
|
22
|
+
|
23
|
+
Alert.TRANSITION_DURATION = 150
|
22
24
|
|
23
25
|
Alert.prototype.close = function (e) {
|
24
26
|
var $this = $(this)
|
@@ -29,12 +31,13 @@
|
|
29
31
|
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
30
32
|
}
|
31
33
|
|
32
|
-
|
34
|
+
selector = selector === '#' ? [] : selector
|
35
|
+
var $parent = $(document).find(selector)
|
33
36
|
|
34
37
|
if (e) e.preventDefault()
|
35
38
|
|
36
39
|
if (!$parent.length) {
|
37
|
-
$parent = $this.
|
40
|
+
$parent = $this.closest('.alert')
|
38
41
|
}
|
39
42
|
|
40
43
|
$parent.trigger(e = $.Event('close.bs.alert'))
|
@@ -51,7 +54,7 @@
|
|
51
54
|
$.support.transition && $parent.hasClass('fade') ?
|
52
55
|
$parent
|
53
56
|
.one('bsTransitionEnd', removeElement)
|
54
|
-
.emulateTransitionEnd(
|
57
|
+
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
|
55
58
|
removeElement()
|
56
59
|
}
|
57
60
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/* ========================================================================
|
2
|
-
* Bootstrap: button.js v3.
|
3
|
-
*
|
2
|
+
* Bootstrap: button.js v3.4.1
|
3
|
+
* https://getbootstrap.com/docs/3.4/javascript/#buttons
|
4
4
|
* ========================================================================
|
5
|
-
* Copyright 2011-
|
5
|
+
* Copyright 2011-2019 Twitter, Inc.
|
6
6
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
7
7
|
* ======================================================================== */
|
8
8
|
|
@@ -19,7 +19,7 @@
|
|
19
19
|
this.isLoading = false
|
20
20
|
}
|
21
21
|
|
22
|
-
Button.VERSION = '3.
|
22
|
+
Button.VERSION = '3.4.1'
|
23
23
|
|
24
24
|
Button.DEFAULTS = {
|
25
25
|
loadingText: 'loading...'
|
@@ -31,20 +31,20 @@
|
|
31
31
|
var val = $el.is('input') ? 'val' : 'html'
|
32
32
|
var data = $el.data()
|
33
33
|
|
34
|
-
state
|
34
|
+
state += 'Text'
|
35
35
|
|
36
36
|
if (data.resetText == null) $el.data('resetText', $el[val]())
|
37
37
|
|
38
|
-
$el[val](data[state] == null ? this.options[state] : data[state])
|
39
|
-
|
40
38
|
// push to event loop to allow forms to submit
|
41
39
|
setTimeout($.proxy(function () {
|
40
|
+
$el[val](data[state] == null ? this.options[state] : data[state])
|
41
|
+
|
42
42
|
if (state == 'loadingText') {
|
43
43
|
this.isLoading = true
|
44
|
-
$el.addClass(d).attr(d, d)
|
44
|
+
$el.addClass(d).attr(d, d).prop(d, true)
|
45
45
|
} else if (this.isLoading) {
|
46
46
|
this.isLoading = false
|
47
|
-
$el.removeClass(d).removeAttr(d)
|
47
|
+
$el.removeClass(d).removeAttr(d).prop(d, false)
|
48
48
|
}
|
49
49
|
}, this), 0)
|
50
50
|
}
|
@@ -56,13 +56,19 @@
|
|
56
56
|
if ($parent.length) {
|
57
57
|
var $input = this.$element.find('input')
|
58
58
|
if ($input.prop('type') == 'radio') {
|
59
|
-
if ($input.prop('checked')
|
60
|
-
|
59
|
+
if ($input.prop('checked')) changed = false
|
60
|
+
$parent.find('.active').removeClass('active')
|
61
|
+
this.$element.addClass('active')
|
62
|
+
} else if ($input.prop('type') == 'checkbox') {
|
63
|
+
if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
|
64
|
+
this.$element.toggleClass('active')
|
61
65
|
}
|
62
|
-
|
66
|
+
$input.prop('checked', this.$element.hasClass('active'))
|
67
|
+
if (changed) $input.trigger('change')
|
68
|
+
} else {
|
69
|
+
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
70
|
+
this.$element.toggleClass('active')
|
63
71
|
}
|
64
|
-
|
65
|
-
if (changed) this.$element.toggleClass('active')
|
66
72
|
}
|
67
73
|
|
68
74
|
|
@@ -100,11 +106,20 @@
|
|
100
106
|
// BUTTON DATA-API
|
101
107
|
// ===============
|
102
108
|
|
103
|
-
$(document)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
$(document)
|
110
|
+
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
111
|
+
var $btn = $(e.target).closest('.btn')
|
112
|
+
Plugin.call($btn, 'toggle')
|
113
|
+
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
|
114
|
+
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
|
115
|
+
e.preventDefault()
|
116
|
+
// The target component still receive the focus
|
117
|
+
if ($btn.is('input,button')) $btn.trigger('focus')
|
118
|
+
else $btn.find('input:visible,button:visible').first().trigger('focus')
|
119
|
+
}
|
120
|
+
})
|
121
|
+
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
122
|
+
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
|
123
|
+
})
|
109
124
|
|
110
125
|
}(jQuery);
|
@@ -1,8 +1,8 @@
|
|
1
1
|
/* ========================================================================
|
2
|
-
* Bootstrap: carousel.js v3.
|
3
|
-
*
|
2
|
+
* Bootstrap: carousel.js v3.4.1
|
3
|
+
* https://getbootstrap.com/docs/3.4/javascript/#carousel
|
4
4
|
* ========================================================================
|
5
|
-
* Copyright 2011-
|
5
|
+
* Copyright 2011-2019 Twitter, Inc.
|
6
6
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
7
7
|
* ======================================================================== */
|
8
8
|
|
@@ -14,29 +14,35 @@
|
|
14
14
|
// =========================
|
15
15
|
|
16
16
|
var Carousel = function (element, options) {
|
17
|
-
this.$element = $(element)
|
17
|
+
this.$element = $(element)
|
18
18
|
this.$indicators = this.$element.find('.carousel-indicators')
|
19
19
|
this.options = options
|
20
|
-
this.paused =
|
21
|
-
this.sliding =
|
22
|
-
this.interval =
|
23
|
-
this.$active =
|
20
|
+
this.paused = null
|
21
|
+
this.sliding = null
|
22
|
+
this.interval = null
|
23
|
+
this.$active = null
|
24
24
|
this.$items = null
|
25
25
|
|
26
|
-
this.options.
|
26
|
+
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
27
|
+
|
28
|
+
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
|
27
29
|
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
|
28
30
|
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
29
31
|
}
|
30
32
|
|
31
|
-
Carousel.VERSION = '3.
|
33
|
+
Carousel.VERSION = '3.4.1'
|
34
|
+
|
35
|
+
Carousel.TRANSITION_DURATION = 600
|
32
36
|
|
33
37
|
Carousel.DEFAULTS = {
|
34
38
|
interval: 5000,
|
35
39
|
pause: 'hover',
|
36
|
-
wrap: true
|
40
|
+
wrap: true,
|
41
|
+
keyboard: true
|
37
42
|
}
|
38
43
|
|
39
44
|
Carousel.prototype.keydown = function (e) {
|
45
|
+
if (/input|textarea/i.test(e.target.tagName)) return
|
40
46
|
switch (e.which) {
|
41
47
|
case 37: this.prev(); break
|
42
48
|
case 39: this.next(); break
|
@@ -63,6 +69,16 @@
|
|
63
69
|
return this.$items.index(item || this.$active)
|
64
70
|
}
|
65
71
|
|
72
|
+
Carousel.prototype.getItemForDirection = function (direction, active) {
|
73
|
+
var activeIndex = this.getItemIndex(active)
|
74
|
+
var willWrap = (direction == 'prev' && activeIndex === 0)
|
75
|
+
|| (direction == 'next' && activeIndex == (this.$items.length - 1))
|
76
|
+
if (willWrap && !this.options.wrap) return active
|
77
|
+
var delta = direction == 'prev' ? -1 : 1
|
78
|
+
var itemIndex = (activeIndex + delta) % this.$items.length
|
79
|
+
return this.$items.eq(itemIndex)
|
80
|
+
}
|
81
|
+
|
66
82
|
Carousel.prototype.to = function (pos) {
|
67
83
|
var that = this
|
68
84
|
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
|
@@ -72,7 +88,7 @@
|
|
72
88
|
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
|
73
89
|
if (activeIndex == pos) return this.pause().cycle()
|
74
90
|
|
75
|
-
return this.slide(pos > activeIndex ? 'next' : 'prev',
|
91
|
+
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
|
76
92
|
}
|
77
93
|
|
78
94
|
Carousel.prototype.pause = function (e) {
|
@@ -100,17 +116,11 @@
|
|
100
116
|
|
101
117
|
Carousel.prototype.slide = function (type, next) {
|
102
118
|
var $active = this.$element.find('.item.active')
|
103
|
-
var $next = next || $active
|
119
|
+
var $next = next || this.getItemForDirection(type, $active)
|
104
120
|
var isCycling = this.interval
|
105
121
|
var direction = type == 'next' ? 'left' : 'right'
|
106
|
-
var fallback = type == 'next' ? 'first' : 'last'
|
107
122
|
var that = this
|
108
123
|
|
109
|
-
if (!$next.length) {
|
110
|
-
if (!this.options.wrap) return
|
111
|
-
$next = this.$element.find('.item')[fallback]()
|
112
|
-
}
|
113
|
-
|
114
124
|
if ($next.hasClass('active')) return (this.sliding = false)
|
115
125
|
|
116
126
|
var relatedTarget = $next[0]
|
@@ -134,7 +144,9 @@
|
|
134
144
|
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
|
135
145
|
if ($.support.transition && this.$element.hasClass('slide')) {
|
136
146
|
$next.addClass(type)
|
137
|
-
$next
|
147
|
+
if (typeof $next === 'object' && $next.length) {
|
148
|
+
$next[0].offsetWidth // force reflow
|
149
|
+
}
|
138
150
|
$active.addClass(direction)
|
139
151
|
$next.addClass(direction)
|
140
152
|
$active
|
@@ -146,7 +158,7 @@
|
|
146
158
|
that.$element.trigger(slidEvent)
|
147
159
|
}, 0)
|
148
160
|
})
|
149
|
-
.emulateTransitionEnd(
|
161
|
+
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
|
150
162
|
} else {
|
151
163
|
$active.removeClass('active')
|
152
164
|
$next.addClass('active')
|
@@ -195,11 +207,18 @@
|
|
195
207
|
// CAROUSEL DATA-API
|
196
208
|
// =================
|
197
209
|
|
198
|
-
|
199
|
-
var href
|
210
|
+
var clickHandler = function (e) {
|
200
211
|
var $this = $(this)
|
201
|
-
var
|
212
|
+
var href = $this.attr('href')
|
213
|
+
if (href) {
|
214
|
+
href = href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
215
|
+
}
|
216
|
+
|
217
|
+
var target = $this.attr('data-target') || href
|
218
|
+
var $target = $(document).find(target)
|
219
|
+
|
202
220
|
if (!$target.hasClass('carousel')) return
|
221
|
+
|
203
222
|
var options = $.extend({}, $target.data(), $this.data())
|
204
223
|
var slideIndex = $this.attr('data-slide-to')
|
205
224
|
if (slideIndex) options.interval = false
|
@@ -211,7 +230,11 @@
|
|
211
230
|
}
|
212
231
|
|
213
232
|
e.preventDefault()
|
214
|
-
}
|
233
|
+
}
|
234
|
+
|
235
|
+
$(document)
|
236
|
+
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
|
237
|
+
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
|
215
238
|
|
216
239
|
$(window).on('load', function () {
|
217
240
|
$('[data-ride="carousel"]').each(function () {
|
@@ -1,11 +1,12 @@
|
|
1
1
|
/* ========================================================================
|
2
|
-
* Bootstrap: collapse.js v3.
|
3
|
-
*
|
2
|
+
* Bootstrap: collapse.js v3.4.1
|
3
|
+
* https://getbootstrap.com/docs/3.4/javascript/#collapse
|
4
4
|
* ========================================================================
|
5
|
-
* Copyright 2011-
|
5
|
+
* Copyright 2011-2019 Twitter, Inc.
|
6
6
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
7
7
|
* ======================================================================== */
|
8
8
|
|
9
|
+
/* jshint latedef: false */
|
9
10
|
|
10
11
|
+function ($) {
|
11
12
|
'use strict';
|
@@ -16,13 +17,22 @@
|
|
16
17
|
var Collapse = function (element, options) {
|
17
18
|
this.$element = $(element)
|
18
19
|
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
20
|
+
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
21
|
+
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
19
22
|
this.transitioning = null
|
20
23
|
|
21
|
-
if (this.options.parent)
|
24
|
+
if (this.options.parent) {
|
25
|
+
this.$parent = this.getParent()
|
26
|
+
} else {
|
27
|
+
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
28
|
+
}
|
29
|
+
|
22
30
|
if (this.options.toggle) this.toggle()
|
23
31
|
}
|
24
32
|
|
25
|
-
Collapse.VERSION = '3.
|
33
|
+
Collapse.VERSION = '3.4.1'
|
34
|
+
|
35
|
+
Collapse.TRANSITION_DURATION = 350
|
26
36
|
|
27
37
|
Collapse.DEFAULTS = {
|
28
38
|
toggle: true
|
@@ -36,17 +46,21 @@
|
|
36
46
|
Collapse.prototype.show = function () {
|
37
47
|
if (this.transitioning || this.$element.hasClass('in')) return
|
38
48
|
|
49
|
+
var activesData
|
50
|
+
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
51
|
+
|
52
|
+
if (actives && actives.length) {
|
53
|
+
activesData = actives.data('bs.collapse')
|
54
|
+
if (activesData && activesData.transitioning) return
|
55
|
+
}
|
56
|
+
|
39
57
|
var startEvent = $.Event('show.bs.collapse')
|
40
58
|
this.$element.trigger(startEvent)
|
41
59
|
if (startEvent.isDefaultPrevented()) return
|
42
60
|
|
43
|
-
var actives = this.$parent && this.$parent.find('> .panel > .in')
|
44
|
-
|
45
61
|
if (actives && actives.length) {
|
46
|
-
var hasData = actives.data('bs.collapse')
|
47
|
-
if (hasData && hasData.transitioning) return
|
48
62
|
Plugin.call(actives, 'hide')
|
49
|
-
|
63
|
+
activesData || actives.data('bs.collapse', null)
|
50
64
|
}
|
51
65
|
|
52
66
|
var dimension = this.dimension()
|
@@ -54,6 +68,11 @@
|
|
54
68
|
this.$element
|
55
69
|
.removeClass('collapse')
|
56
70
|
.addClass('collapsing')[dimension](0)
|
71
|
+
.attr('aria-expanded', true)
|
72
|
+
|
73
|
+
this.$trigger
|
74
|
+
.removeClass('collapsed')
|
75
|
+
.attr('aria-expanded', true)
|
57
76
|
|
58
77
|
this.transitioning = 1
|
59
78
|
|
@@ -72,7 +91,7 @@
|
|
72
91
|
|
73
92
|
this.$element
|
74
93
|
.one('bsTransitionEnd', $.proxy(complete, this))
|
75
|
-
.emulateTransitionEnd(
|
94
|
+
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
76
95
|
}
|
77
96
|
|
78
97
|
Collapse.prototype.hide = function () {
|
@@ -88,17 +107,21 @@
|
|
88
107
|
|
89
108
|
this.$element
|
90
109
|
.addClass('collapsing')
|
91
|
-
.removeClass('collapse')
|
92
|
-
.
|
110
|
+
.removeClass('collapse in')
|
111
|
+
.attr('aria-expanded', false)
|
112
|
+
|
113
|
+
this.$trigger
|
114
|
+
.addClass('collapsed')
|
115
|
+
.attr('aria-expanded', false)
|
93
116
|
|
94
117
|
this.transitioning = 1
|
95
118
|
|
96
119
|
var complete = function () {
|
97
120
|
this.transitioning = 0
|
98
121
|
this.$element
|
99
|
-
.trigger('hidden.bs.collapse')
|
100
122
|
.removeClass('collapsing')
|
101
123
|
.addClass('collapse')
|
124
|
+
.trigger('hidden.bs.collapse')
|
102
125
|
}
|
103
126
|
|
104
127
|
if (!$.support.transition) return complete.call(this)
|
@@ -106,13 +129,40 @@
|
|
106
129
|
this.$element
|
107
130
|
[dimension](0)
|
108
131
|
.one('bsTransitionEnd', $.proxy(complete, this))
|
109
|
-
.emulateTransitionEnd(
|
132
|
+
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
110
133
|
}
|
111
134
|
|
112
135
|
Collapse.prototype.toggle = function () {
|
113
136
|
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
114
137
|
}
|
115
138
|
|
139
|
+
Collapse.prototype.getParent = function () {
|
140
|
+
return $(document).find(this.options.parent)
|
141
|
+
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
142
|
+
.each($.proxy(function (i, element) {
|
143
|
+
var $element = $(element)
|
144
|
+
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
145
|
+
}, this))
|
146
|
+
.end()
|
147
|
+
}
|
148
|
+
|
149
|
+
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
150
|
+
var isOpen = $element.hasClass('in')
|
151
|
+
|
152
|
+
$element.attr('aria-expanded', isOpen)
|
153
|
+
$trigger
|
154
|
+
.toggleClass('collapsed', !isOpen)
|
155
|
+
.attr('aria-expanded', isOpen)
|
156
|
+
}
|
157
|
+
|
158
|
+
function getTargetFromTrigger($trigger) {
|
159
|
+
var href
|
160
|
+
var target = $trigger.attr('data-target')
|
161
|
+
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
162
|
+
|
163
|
+
return $(document).find(target)
|
164
|
+
}
|
165
|
+
|
116
166
|
|
117
167
|
// COLLAPSE PLUGIN DEFINITION
|
118
168
|
// ==========================
|
@@ -123,7 +173,7 @@
|
|
123
173
|
var data = $this.data('bs.collapse')
|
124
174
|
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
125
175
|
|
126
|
-
if (!data && options.toggle && option
|
176
|
+
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
127
177
|
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
128
178
|
if (typeof option == 'string') data[option]()
|
129
179
|
})
|
@@ -148,21 +198,13 @@
|
|
148
198
|
// =================
|
149
199
|
|
150
200
|
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
151
|
-
var href
|
152
201
|
var $this = $(this)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
var $target = $
|
202
|
+
|
203
|
+
if (!$this.attr('data-target')) e.preventDefault()
|
204
|
+
|
205
|
+
var $target = getTargetFromTrigger($this)
|
157
206
|
var data = $target.data('bs.collapse')
|
158
207
|
var option = data ? 'toggle' : $this.data()
|
159
|
-
var parent = $this.attr('data-parent')
|
160
|
-
var $parent = parent && $(parent)
|
161
|
-
|
162
|
-
if (!data || !data.transitioning) {
|
163
|
-
if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
|
164
|
-
$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
|
165
|
-
}
|
166
208
|
|
167
209
|
Plugin.call($target, option)
|
168
210
|
})
|