3.0.0 -> 3.0.1
[bootswatch] / bower_components / bootstrap / js / collapse.js
1 /* ========================================================================
2  * Bootstrap: collapse.js v3.0.0
3  * http://getbootstrap.com/javascript/#collapse
4  * ========================================================================
5  * Copyright 2013 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
20
21 +function ($) { "use strict";
22
23   // COLLAPSE PUBLIC CLASS DEFINITION
24   // ================================
25
26   var Collapse = function (element, options) {
27     this.$element      = $(element)
28     this.options       = $.extend({}, Collapse.DEFAULTS, options)
29     this.transitioning = null
30
31     if (this.options.parent) this.$parent = $(this.options.parent)
32     if (this.options.toggle) this.toggle()
33   }
34
35   Collapse.DEFAULTS = {
36     toggle: true
37   }
38
39   Collapse.prototype.dimension = function () {
40     var hasWidth = this.$element.hasClass('width')
41     return hasWidth ? 'width' : 'height'
42   }
43
44   Collapse.prototype.show = function () {
45     if (this.transitioning || this.$element.hasClass('in')) return
46
47     var startEvent = $.Event('show.bs.collapse')
48     this.$element.trigger(startEvent)
49     if (startEvent.isDefaultPrevented()) return
50
51     var actives = this.$parent && this.$parent.find('> .panel > .in')
52
53     if (actives && actives.length) {
54       var hasData = actives.data('bs.collapse')
55       if (hasData && hasData.transitioning) return
56       actives.collapse('hide')
57       hasData || actives.data('bs.collapse', null)
58     }
59
60     var dimension = this.dimension()
61
62     this.$element
63       .removeClass('collapse')
64       .addClass('collapsing')
65       [dimension](0)
66
67     this.transitioning = 1
68
69     var complete = function () {
70       this.$element
71         .removeClass('collapsing')
72         .addClass('in')
73         [dimension]('auto')
74       this.transitioning = 0
75       this.$element.trigger('shown.bs.collapse')
76     }
77
78     if (!$.support.transition) return complete.call(this)
79
80     var scrollSize = $.camelCase(['scroll', dimension].join('-'))
81
82     this.$element
83       .one($.support.transition.end, $.proxy(complete, this))
84       .emulateTransitionEnd(350)
85       [dimension](this.$element[0][scrollSize])
86   }
87
88   Collapse.prototype.hide = function () {
89     if (this.transitioning || !this.$element.hasClass('in')) return
90
91     var startEvent = $.Event('hide.bs.collapse')
92     this.$element.trigger(startEvent)
93     if (startEvent.isDefaultPrevented()) return
94
95     var dimension = this.dimension()
96
97     this.$element
98       [dimension](this.$element[dimension]())
99       [0].offsetHeight
100
101     this.$element
102       .addClass('collapsing')
103       .removeClass('collapse')
104       .removeClass('in')
105
106     this.transitioning = 1
107
108     var complete = function () {
109       this.transitioning = 0
110       this.$element
111         .trigger('hidden.bs.collapse')
112         .removeClass('collapsing')
113         .addClass('collapse')
114     }
115
116     if (!$.support.transition) return complete.call(this)
117
118     this.$element
119       [dimension](0)
120       .one($.support.transition.end, $.proxy(complete, this))
121       .emulateTransitionEnd(350)
122   }
123
124   Collapse.prototype.toggle = function () {
125     this[this.$element.hasClass('in') ? 'hide' : 'show']()
126   }
127
128
129   // COLLAPSE PLUGIN DEFINITION
130   // ==========================
131
132   var old = $.fn.collapse
133
134   $.fn.collapse = function (option) {
135     return this.each(function () {
136       var $this   = $(this)
137       var data    = $this.data('bs.collapse')
138       var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
139
140       if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
141       if (typeof option == 'string') data[option]()
142     })
143   }
144
145   $.fn.collapse.Constructor = Collapse
146
147
148   // COLLAPSE NO CONFLICT
149   // ====================
150
151   $.fn.collapse.noConflict = function () {
152     $.fn.collapse = old
153     return this
154   }
155
156
157   // COLLAPSE DATA-API
158   // =================
159
160   $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
161     var $this   = $(this), href
162     var target  = $this.attr('data-target')
163         || e.preventDefault()
164         || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
165     var $target = $(target)
166     var data    = $target.data('bs.collapse')
167     var option  = data ? 'toggle' : $this.data()
168     var parent  = $this.attr('data-parent')
169     var $parent = parent && $(parent)
170
171     if (!data || !data.transitioning) {
172       if ($parent) $parent.find('[data-toggle=collapse][data-parent="' + parent + '"]').not($this).addClass('collapsed')
173       $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
174     }
175
176     $target.collapse(option)
177   })
178
179 }(window.jQuery);