|
1 /* ======================================================================== |
|
2 * Bootstrap: collapse.js v3.3.5 |
|
3 * http://getbootstrap.com/javascript/#collapse |
|
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 // 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 = $('[data-toggle="collapse"][href="#' + element.id + '"],' + |
|
20 '[data-toggle="collapse"][data-target="#' + element.id + '"]') |
|
21 this.transitioning = null |
|
22 |
|
23 if (this.options.parent) { |
|
24 this.$parent = this.getParent() |
|
25 } else { |
|
26 this.addAriaAndCollapsedClass(this.$element, this.$trigger) |
|
27 } |
|
28 |
|
29 if (this.options.toggle) this.toggle() |
|
30 } |
|
31 |
|
32 Collapse.VERSION = '3.3.5' |
|
33 |
|
34 Collapse.TRANSITION_DURATION = 350 |
|
35 |
|
36 Collapse.DEFAULTS = { |
|
37 toggle: true |
|
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.children('.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 && /show|hide/.test(option)) 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' : $this.data() |
|
207 |
|
208 Plugin.call($target, option) |
|
209 }) |
|
210 |
|
211 }(jQuery); |