]> git.ipfire.org Git - ipfire.org.git/blame - src/scss/bootstrap-4.0.0-alpha.6/js/src/tab.js
Introduce autotools
[ipfire.org.git] / src / scss / bootstrap-4.0.0-alpha.6 / js / src / tab.js
CommitLineData
91e44d91
S
1import Util from './util'
2
3
4/**
5 * --------------------------------------------------------------------------
6 * Bootstrap (v4.0.0-alpha.6): tab.js
7 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8 * --------------------------------------------------------------------------
9 */
10
11const Tab = (($) => {
12
13
14 /**
15 * ------------------------------------------------------------------------
16 * Constants
17 * ------------------------------------------------------------------------
18 */
19
20 const NAME = 'tab'
21 const VERSION = '4.0.0-alpha.6'
22 const DATA_KEY = 'bs.tab'
23 const EVENT_KEY = `.${DATA_KEY}`
24 const DATA_API_KEY = '.data-api'
25 const JQUERY_NO_CONFLICT = $.fn[NAME]
26 const TRANSITION_DURATION = 150
27
28 const Event = {
29 HIDE : `hide${EVENT_KEY}`,
30 HIDDEN : `hidden${EVENT_KEY}`,
31 SHOW : `show${EVENT_KEY}`,
32 SHOWN : `shown${EVENT_KEY}`,
33 CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
34 }
35
36 const ClassName = {
37 DROPDOWN_MENU : 'dropdown-menu',
38 ACTIVE : 'active',
39 DISABLED : 'disabled',
40 FADE : 'fade',
41 SHOW : 'show'
42 }
43
44 const Selector = {
45 A : 'a',
46 LI : 'li',
47 DROPDOWN : '.dropdown',
48 LIST : 'ul:not(.dropdown-menu), ol:not(.dropdown-menu), nav:not(.dropdown-menu)',
49 FADE_CHILD : '> .nav-item .fade, > .fade',
50 ACTIVE : '.active',
51 ACTIVE_CHILD : '> .nav-item > .active, > .active',
52 DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]',
53 DROPDOWN_TOGGLE : '.dropdown-toggle',
54 DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu .active'
55 }
56
57
58 /**
59 * ------------------------------------------------------------------------
60 * Class Definition
61 * ------------------------------------------------------------------------
62 */
63
64 class Tab {
65
66 constructor(element) {
67 this._element = element
68 }
69
70
71 // getters
72
73 static get VERSION() {
74 return VERSION
75 }
76
77
78 // public
79
80 show() {
81 if (this._element.parentNode &&
82 this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
83 $(this._element).hasClass(ClassName.ACTIVE) ||
84 $(this._element).hasClass(ClassName.DISABLED)) {
85 return
86 }
87
88 let target
89 let previous
90 const listElement = $(this._element).closest(Selector.LIST)[0]
91 const selector = Util.getSelectorFromElement(this._element)
92
93 if (listElement) {
94 previous = $.makeArray($(listElement).find(Selector.ACTIVE))
95 previous = previous[previous.length - 1]
96 }
97
98 const hideEvent = $.Event(Event.HIDE, {
99 relatedTarget: this._element
100 })
101
102 const showEvent = $.Event(Event.SHOW, {
103 relatedTarget: previous
104 })
105
106 if (previous) {
107 $(previous).trigger(hideEvent)
108 }
109
110 $(this._element).trigger(showEvent)
111
112 if (showEvent.isDefaultPrevented() ||
113 hideEvent.isDefaultPrevented()) {
114 return
115 }
116
117 if (selector) {
118 target = $(selector)[0]
119 }
120
121 this._activate(
122 this._element,
123 listElement
124 )
125
126 const complete = () => {
127 const hiddenEvent = $.Event(Event.HIDDEN, {
128 relatedTarget: this._element
129 })
130
131 const shownEvent = $.Event(Event.SHOWN, {
132 relatedTarget: previous
133 })
134
135 $(previous).trigger(hiddenEvent)
136 $(this._element).trigger(shownEvent)
137 }
138
139 if (target) {
140 this._activate(target, target.parentNode, complete)
141 } else {
142 complete()
143 }
144 }
145
146 dispose() {
147 $.removeClass(this._element, DATA_KEY)
148 this._element = null
149 }
150
151
152 // private
153
154 _activate(element, container, callback) {
155 const active = $(container).find(Selector.ACTIVE_CHILD)[0]
156 const isTransitioning = callback
157 && Util.supportsTransitionEnd()
158 && (active && $(active).hasClass(ClassName.FADE)
159 || Boolean($(container).find(Selector.FADE_CHILD)[0]))
160
161 const complete = () => this._transitionComplete(
162 element,
163 active,
164 isTransitioning,
165 callback
166 )
167
168 if (active && isTransitioning) {
169 $(active)
170 .one(Util.TRANSITION_END, complete)
171 .emulateTransitionEnd(TRANSITION_DURATION)
172
173 } else {
174 complete()
175 }
176
177 if (active) {
178 $(active).removeClass(ClassName.SHOW)
179 }
180 }
181
182 _transitionComplete(element, active, isTransitioning, callback) {
183 if (active) {
184 $(active).removeClass(ClassName.ACTIVE)
185
186 const dropdownChild = $(active.parentNode).find(
187 Selector.DROPDOWN_ACTIVE_CHILD
188 )[0]
189
190 if (dropdownChild) {
191 $(dropdownChild).removeClass(ClassName.ACTIVE)
192 }
193
194 active.setAttribute('aria-expanded', false)
195 }
196
197 $(element).addClass(ClassName.ACTIVE)
198 element.setAttribute('aria-expanded', true)
199
200 if (isTransitioning) {
201 Util.reflow(element)
202 $(element).addClass(ClassName.SHOW)
203 } else {
204 $(element).removeClass(ClassName.FADE)
205 }
206
207 if (element.parentNode &&
208 $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
209
210 const dropdownElement = $(element).closest(Selector.DROPDOWN)[0]
211 if (dropdownElement) {
212 $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE)
213 }
214
215 element.setAttribute('aria-expanded', true)
216 }
217
218 if (callback) {
219 callback()
220 }
221 }
222
223
224 // static
225
226 static _jQueryInterface(config) {
227 return this.each(function () {
228 const $this = $(this)
229 let data = $this.data(DATA_KEY)
230
231 if (!data) {
232 data = new Tab(this)
233 $this.data(DATA_KEY, data)
234 }
235
236 if (typeof config === 'string') {
237 if (data[config] === undefined) {
238 throw new Error(`No method named "${config}"`)
239 }
240 data[config]()
241 }
242 })
243 }
244
245 }
246
247
248 /**
249 * ------------------------------------------------------------------------
250 * Data Api implementation
251 * ------------------------------------------------------------------------
252 */
253
254 $(document)
255 .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
256 event.preventDefault()
257 Tab._jQueryInterface.call($(this), 'show')
258 })
259
260
261 /**
262 * ------------------------------------------------------------------------
263 * jQuery
264 * ------------------------------------------------------------------------
265 */
266
267 $.fn[NAME] = Tab._jQueryInterface
268 $.fn[NAME].Constructor = Tab
269 $.fn[NAME].noConflict = function () {
270 $.fn[NAME] = JQUERY_NO_CONFLICT
271 return Tab._jQueryInterface
272 }
273
274 return Tab
275
276})(jQuery)
277
278export default Tab