corrade-http-templates – Blame information for rev 61

Subversion Repositories:
Rev:
Rev Author Line No. Line
61 office 1 import $ from 'jquery'
2 import Util from './util'
3  
4 /**
5 * --------------------------------------------------------------------------
6 * Bootstrap (v4.1.3): collapse.js
7 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8 * --------------------------------------------------------------------------
9 */
10  
11 const Collapse = (($) => {
12 /**
13 * ------------------------------------------------------------------------
14 * Constants
15 * ------------------------------------------------------------------------
16 */
17  
18 const NAME = 'collapse'
19 const VERSION = '4.1.3'
20 const DATA_KEY = 'bs.collapse'
21 const EVENT_KEY = `.${DATA_KEY}`
22 const DATA_API_KEY = '.data-api'
23 const JQUERY_NO_CONFLICT = $.fn[NAME]
24  
25 const Default = {
26 toggle : true,
27 parent : ''
28 }
29  
30 const DefaultType = {
31 toggle : 'boolean',
32 parent : '(string|element)'
33 }
34  
35 const Event = {
36 SHOW : `show${EVENT_KEY}`,
37 SHOWN : `shown${EVENT_KEY}`,
38 HIDE : `hide${EVENT_KEY}`,
39 HIDDEN : `hidden${EVENT_KEY}`,
40 CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
41 }
42  
43 const ClassName = {
44 SHOW : 'show',
45 COLLAPSE : 'collapse',
46 COLLAPSING : 'collapsing',
47 COLLAPSED : 'collapsed'
48 }
49  
50 const Dimension = {
51 WIDTH : 'width',
52 HEIGHT : 'height'
53 }
54  
55 const Selector = {
56 ACTIVES : '.show, .collapsing',
57 DATA_TOGGLE : '[data-toggle="collapse"]'
58 }
59  
60 /**
61 * ------------------------------------------------------------------------
62 * Class Definition
63 * ------------------------------------------------------------------------
64 */
65  
66 class Collapse {
67 constructor(element, config) {
68 this._isTransitioning = false
69 this._element = element
70 this._config = this._getConfig(config)
71 this._triggerArray = $.makeArray(document.querySelectorAll(
72 `[data-toggle="collapse"][href="#${element.id}"],` +
73 `[data-toggle="collapse"][data-target="#${element.id}"]`
74 ))
75 const toggleList = [].slice.call(document.querySelectorAll(Selector.DATA_TOGGLE))
76 for (let i = 0, len = toggleList.length; i < len; i++) {
77 const elem = toggleList[i]
78 const selector = Util.getSelectorFromElement(elem)
79 const filterElement = [].slice.call(document.querySelectorAll(selector))
80 .filter((foundElem) => foundElem === element)
81  
82 if (selector !== null && filterElement.length > 0) {
83 this._selector = selector
84 this._triggerArray.push(elem)
85 }
86 }
87  
88 this._parent = this._config.parent ? this._getParent() : null
89  
90 if (!this._config.parent) {
91 this._addAriaAndCollapsedClass(this._element, this._triggerArray)
92 }
93  
94 if (this._config.toggle) {
95 this.toggle()
96 }
97 }
98  
99 // Getters
100  
101 static get VERSION() {
102 return VERSION
103 }
104  
105 static get Default() {
106 return Default
107 }
108  
109 // Public
110  
111 toggle() {
112 if ($(this._element).hasClass(ClassName.SHOW)) {
113 this.hide()
114 } else {
115 this.show()
116 }
117 }
118  
119 show() {
120 if (this._isTransitioning ||
121 $(this._element).hasClass(ClassName.SHOW)) {
122 return
123 }
124  
125 let actives
126 let activesData
127  
128 if (this._parent) {
129 actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES))
130 .filter((elem) => elem.getAttribute('data-parent') === this._config.parent)
131  
132 if (actives.length === 0) {
133 actives = null
134 }
135 }
136  
137 if (actives) {
138 activesData = $(actives).not(this._selector).data(DATA_KEY)
139 if (activesData && activesData._isTransitioning) {
140 return
141 }
142 }
143  
144 const startEvent = $.Event(Event.SHOW)
145 $(this._element).trigger(startEvent)
146 if (startEvent.isDefaultPrevented()) {
147 return
148 }
149  
150 if (actives) {
151 Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')
152 if (!activesData) {
153 $(actives).data(DATA_KEY, null)
154 }
155 }
156  
157 const dimension = this._getDimension()
158  
159 $(this._element)
160 .removeClass(ClassName.COLLAPSE)
161 .addClass(ClassName.COLLAPSING)
162  
163 this._element.style[dimension] = 0
164  
165 if (this._triggerArray.length) {
166 $(this._triggerArray)
167 .removeClass(ClassName.COLLAPSED)
168 .attr('aria-expanded', true)
169 }
170  
171 this.setTransitioning(true)
172  
173 const complete = () => {
174 $(this._element)
175 .removeClass(ClassName.COLLAPSING)
176 .addClass(ClassName.COLLAPSE)
177 .addClass(ClassName.SHOW)
178  
179 this._element.style[dimension] = ''
180  
181 this.setTransitioning(false)
182  
183 $(this._element).trigger(Event.SHOWN)
184 }
185  
186 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)
187 const scrollSize = `scroll${capitalizedDimension}`
188 const transitionDuration = Util.getTransitionDurationFromElement(this._element)
189  
190 $(this._element)
191 .one(Util.TRANSITION_END, complete)
192 .emulateTransitionEnd(transitionDuration)
193  
194 this._element.style[dimension] = `${this._element[scrollSize]}px`
195 }
196  
197 hide() {
198 if (this._isTransitioning ||
199 !$(this._element).hasClass(ClassName.SHOW)) {
200 return
201 }
202  
203 const startEvent = $.Event(Event.HIDE)
204 $(this._element).trigger(startEvent)
205 if (startEvent.isDefaultPrevented()) {
206 return
207 }
208  
209 const dimension = this._getDimension()
210  
211 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`
212  
213 Util.reflow(this._element)
214  
215 $(this._element)
216 .addClass(ClassName.COLLAPSING)
217 .removeClass(ClassName.COLLAPSE)
218 .removeClass(ClassName.SHOW)
219  
220 const triggerArrayLength = this._triggerArray.length
221 if (triggerArrayLength > 0) {
222 for (let i = 0; i < triggerArrayLength; i++) {
223 const trigger = this._triggerArray[i]
224 const selector = Util.getSelectorFromElement(trigger)
225 if (selector !== null) {
226 const $elem = $([].slice.call(document.querySelectorAll(selector)))
227 if (!$elem.hasClass(ClassName.SHOW)) {
228 $(trigger).addClass(ClassName.COLLAPSED)
229 .attr('aria-expanded', false)
230 }
231 }
232 }
233 }
234  
235 this.setTransitioning(true)
236  
237 const complete = () => {
238 this.setTransitioning(false)
239 $(this._element)
240 .removeClass(ClassName.COLLAPSING)
241 .addClass(ClassName.COLLAPSE)
242 .trigger(Event.HIDDEN)
243 }
244  
245 this._element.style[dimension] = ''
246 const transitionDuration = Util.getTransitionDurationFromElement(this._element)
247  
248 $(this._element)
249 .one(Util.TRANSITION_END, complete)
250 .emulateTransitionEnd(transitionDuration)
251 }
252  
253 setTransitioning(isTransitioning) {
254 this._isTransitioning = isTransitioning
255 }
256  
257 dispose() {
258 $.removeData(this._element, DATA_KEY)
259  
260 this._config = null
261 this._parent = null
262 this._element = null
263 this._triggerArray = null
264 this._isTransitioning = null
265 }
266  
267 // Private
268  
269 _getConfig(config) {
270 config = {
271 ...Default,
272 ...config
273 }
274 config.toggle = Boolean(config.toggle) // Coerce string values
275 Util.typeCheckConfig(NAME, config, DefaultType)
276 return config
277 }
278  
279 _getDimension() {
280 const hasWidth = $(this._element).hasClass(Dimension.WIDTH)
281 return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT
282 }
283  
284 _getParent() {
285 let parent = null
286 if (Util.isElement(this._config.parent)) {
287 parent = this._config.parent
288  
289 // It's a jQuery object
290 if (typeof this._config.parent.jquery !== 'undefined') {
291 parent = this._config.parent[0]
292 }
293 } else {
294 parent = document.querySelector(this._config.parent)
295 }
296  
297 const selector =
298 `[data-toggle="collapse"][data-parent="${this._config.parent}"]`
299  
300 const children = [].slice.call(parent.querySelectorAll(selector))
301 $(children).each((i, element) => {
302 this._addAriaAndCollapsedClass(
303 Collapse._getTargetFromElement(element),
304 [element]
305 )
306 })
307  
308 return parent
309 }
310  
311 _addAriaAndCollapsedClass(element, triggerArray) {
312 if (element) {
313 const isOpen = $(element).hasClass(ClassName.SHOW)
314  
315 if (triggerArray.length) {
316 $(triggerArray)
317 .toggleClass(ClassName.COLLAPSED, !isOpen)
318 .attr('aria-expanded', isOpen)
319 }
320 }
321 }
322  
323 // Static
324  
325 static _getTargetFromElement(element) {
326 const selector = Util.getSelectorFromElement(element)
327 return selector ? document.querySelector(selector) : null
328 }
329  
330 static _jQueryInterface(config) {
331 return this.each(function () {
332 const $this = $(this)
333 let data = $this.data(DATA_KEY)
334 const _config = {
335 ...Default,
336 ...$this.data(),
337 ...typeof config === 'object' && config ? config : {}
338 }
339  
340 if (!data && _config.toggle && /show|hide/.test(config)) {
341 _config.toggle = false
342 }
343  
344 if (!data) {
345 data = new Collapse(this, _config)
346 $this.data(DATA_KEY, data)
347 }
348  
349 if (typeof config === 'string') {
350 if (typeof data[config] === 'undefined') {
351 throw new TypeError(`No method named "${config}"`)
352 }
353 data[config]()
354 }
355 })
356 }
357 }
358  
359 /**
360 * ------------------------------------------------------------------------
361 * Data Api implementation
362 * ------------------------------------------------------------------------
363 */
364  
365 $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
366 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
367 if (event.currentTarget.tagName === 'A') {
368 event.preventDefault()
369 }
370  
371 const $trigger = $(this)
372 const selector = Util.getSelectorFromElement(this)
373 const selectors = [].slice.call(document.querySelectorAll(selector))
374 $(selectors).each(function () {
375 const $target = $(this)
376 const data = $target.data(DATA_KEY)
377 const config = data ? 'toggle' : $trigger.data()
378 Collapse._jQueryInterface.call($target, config)
379 })
380 })
381  
382 /**
383 * ------------------------------------------------------------------------
384 * jQuery
385 * ------------------------------------------------------------------------
386 */
387  
388 $.fn[NAME] = Collapse._jQueryInterface
389 $.fn[NAME].Constructor = Collapse
390 $.fn[NAME].noConflict = function () {
391 $.fn[NAME] = JQUERY_NO_CONFLICT
392 return Collapse._jQueryInterface
393 }
394  
395 return Collapse
396 })($)
397  
398 export default Collapse