OSDN Git Service

Remove unwanted dependencies
[bytom/vapor.git] / tools / side_chain_tool / web / node_modules / bootstrap / js / src / modal.js
1 import $ from 'jquery'
2 import Util from './util'
3
4 /**
5  * --------------------------------------------------------------------------
6  * Bootstrap (v4.1.3): modal.js
7  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
8  * --------------------------------------------------------------------------
9  */
10
11 const Modal = (($) => {
12   /**
13    * ------------------------------------------------------------------------
14    * Constants
15    * ------------------------------------------------------------------------
16    */
17
18   const NAME               = 'modal'
19   const VERSION            = '4.1.3'
20   const DATA_KEY           = 'bs.modal'
21   const EVENT_KEY          = `.${DATA_KEY}`
22   const DATA_API_KEY       = '.data-api'
23   const JQUERY_NO_CONFLICT = $.fn[NAME]
24   const ESCAPE_KEYCODE     = 27 // KeyboardEvent.which value for Escape (Esc) key
25
26   const Default = {
27     backdrop : true,
28     keyboard : true,
29     focus    : true,
30     show     : true
31   }
32
33   const DefaultType = {
34     backdrop : '(boolean|string)',
35     keyboard : 'boolean',
36     focus    : 'boolean',
37     show     : 'boolean'
38   }
39
40   const Event = {
41     HIDE              : `hide${EVENT_KEY}`,
42     HIDDEN            : `hidden${EVENT_KEY}`,
43     SHOW              : `show${EVENT_KEY}`,
44     SHOWN             : `shown${EVENT_KEY}`,
45     FOCUSIN           : `focusin${EVENT_KEY}`,
46     RESIZE            : `resize${EVENT_KEY}`,
47     CLICK_DISMISS     : `click.dismiss${EVENT_KEY}`,
48     KEYDOWN_DISMISS   : `keydown.dismiss${EVENT_KEY}`,
49     MOUSEUP_DISMISS   : `mouseup.dismiss${EVENT_KEY}`,
50     MOUSEDOWN_DISMISS : `mousedown.dismiss${EVENT_KEY}`,
51     CLICK_DATA_API    : `click${EVENT_KEY}${DATA_API_KEY}`
52   }
53
54   const ClassName = {
55     SCROLLBAR_MEASURER : 'modal-scrollbar-measure',
56     BACKDROP           : 'modal-backdrop',
57     OPEN               : 'modal-open',
58     FADE               : 'fade',
59     SHOW               : 'show'
60   }
61
62   const Selector = {
63     DIALOG             : '.modal-dialog',
64     DATA_TOGGLE        : '[data-toggle="modal"]',
65     DATA_DISMISS       : '[data-dismiss="modal"]',
66     FIXED_CONTENT      : '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
67     STICKY_CONTENT     : '.sticky-top'
68   }
69
70   /**
71    * ------------------------------------------------------------------------
72    * Class Definition
73    * ------------------------------------------------------------------------
74    */
75
76   class Modal {
77     constructor(element, config) {
78       this._config              = this._getConfig(config)
79       this._element             = element
80       this._dialog              = element.querySelector(Selector.DIALOG)
81       this._backdrop            = null
82       this._isShown             = false
83       this._isBodyOverflowing   = false
84       this._ignoreBackdropClick = false
85       this._scrollbarWidth      = 0
86     }
87
88     // Getters
89
90     static get VERSION() {
91       return VERSION
92     }
93
94     static get Default() {
95       return Default
96     }
97
98     // Public
99
100     toggle(relatedTarget) {
101       return this._isShown ? this.hide() : this.show(relatedTarget)
102     }
103
104     show(relatedTarget) {
105       if (this._isTransitioning || this._isShown) {
106         return
107       }
108
109       if ($(this._element).hasClass(ClassName.FADE)) {
110         this._isTransitioning = true
111       }
112
113       const showEvent = $.Event(Event.SHOW, {
114         relatedTarget
115       })
116
117       $(this._element).trigger(showEvent)
118
119       if (this._isShown || showEvent.isDefaultPrevented()) {
120         return
121       }
122
123       this._isShown = true
124
125       this._checkScrollbar()
126       this._setScrollbar()
127
128       this._adjustDialog()
129
130       $(document.body).addClass(ClassName.OPEN)
131
132       this._setEscapeEvent()
133       this._setResizeEvent()
134
135       $(this._element).on(
136         Event.CLICK_DISMISS,
137         Selector.DATA_DISMISS,
138         (event) => this.hide(event)
139       )
140
141       $(this._dialog).on(Event.MOUSEDOWN_DISMISS, () => {
142         $(this._element).one(Event.MOUSEUP_DISMISS, (event) => {
143           if ($(event.target).is(this._element)) {
144             this._ignoreBackdropClick = true
145           }
146         })
147       })
148
149       this._showBackdrop(() => this._showElement(relatedTarget))
150     }
151
152     hide(event) {
153       if (event) {
154         event.preventDefault()
155       }
156
157       if (this._isTransitioning || !this._isShown) {
158         return
159       }
160
161       const hideEvent = $.Event(Event.HIDE)
162
163       $(this._element).trigger(hideEvent)
164
165       if (!this._isShown || hideEvent.isDefaultPrevented()) {
166         return
167       }
168
169       this._isShown = false
170       const transition = $(this._element).hasClass(ClassName.FADE)
171
172       if (transition) {
173         this._isTransitioning = true
174       }
175
176       this._setEscapeEvent()
177       this._setResizeEvent()
178
179       $(document).off(Event.FOCUSIN)
180
181       $(this._element).removeClass(ClassName.SHOW)
182
183       $(this._element).off(Event.CLICK_DISMISS)
184       $(this._dialog).off(Event.MOUSEDOWN_DISMISS)
185
186
187       if (transition) {
188         const transitionDuration  = Util.getTransitionDurationFromElement(this._element)
189
190         $(this._element)
191           .one(Util.TRANSITION_END, (event) => this._hideModal(event))
192           .emulateTransitionEnd(transitionDuration)
193       } else {
194         this._hideModal()
195       }
196     }
197
198     dispose() {
199       $.removeData(this._element, DATA_KEY)
200
201       $(window, document, this._element, this._backdrop).off(EVENT_KEY)
202
203       this._config              = null
204       this._element             = null
205       this._dialog              = null
206       this._backdrop            = null
207       this._isShown             = null
208       this._isBodyOverflowing   = null
209       this._ignoreBackdropClick = null
210       this._scrollbarWidth      = null
211     }
212
213     handleUpdate() {
214       this._adjustDialog()
215     }
216
217     // Private
218
219     _getConfig(config) {
220       config = {
221         ...Default,
222         ...config
223       }
224       Util.typeCheckConfig(NAME, config, DefaultType)
225       return config
226     }
227
228     _showElement(relatedTarget) {
229       const transition = $(this._element).hasClass(ClassName.FADE)
230
231       if (!this._element.parentNode ||
232          this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
233         // Don't move modal's DOM position
234         document.body.appendChild(this._element)
235       }
236
237       this._element.style.display = 'block'
238       this._element.removeAttribute('aria-hidden')
239       this._element.scrollTop = 0
240
241       if (transition) {
242         Util.reflow(this._element)
243       }
244
245       $(this._element).addClass(ClassName.SHOW)
246
247       if (this._config.focus) {
248         this._enforceFocus()
249       }
250
251       const shownEvent = $.Event(Event.SHOWN, {
252         relatedTarget
253       })
254
255       const transitionComplete = () => {
256         if (this._config.focus) {
257           this._element.focus()
258         }
259         this._isTransitioning = false
260         $(this._element).trigger(shownEvent)
261       }
262
263       if (transition) {
264         const transitionDuration  = Util.getTransitionDurationFromElement(this._element)
265
266         $(this._dialog)
267           .one(Util.TRANSITION_END, transitionComplete)
268           .emulateTransitionEnd(transitionDuration)
269       } else {
270         transitionComplete()
271       }
272     }
273
274     _enforceFocus() {
275       $(document)
276         .off(Event.FOCUSIN) // Guard against infinite focus loop
277         .on(Event.FOCUSIN, (event) => {
278           if (document !== event.target &&
279               this._element !== event.target &&
280               $(this._element).has(event.target).length === 0) {
281             this._element.focus()
282           }
283         })
284     }
285
286     _setEscapeEvent() {
287       if (this._isShown && this._config.keyboard) {
288         $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
289           if (event.which === ESCAPE_KEYCODE) {
290             event.preventDefault()
291             this.hide()
292           }
293         })
294       } else if (!this._isShown) {
295         $(this._element).off(Event.KEYDOWN_DISMISS)
296       }
297     }
298
299     _setResizeEvent() {
300       if (this._isShown) {
301         $(window).on(Event.RESIZE, (event) => this.handleUpdate(event))
302       } else {
303         $(window).off(Event.RESIZE)
304       }
305     }
306
307     _hideModal() {
308       this._element.style.display = 'none'
309       this._element.setAttribute('aria-hidden', true)
310       this._isTransitioning = false
311       this._showBackdrop(() => {
312         $(document.body).removeClass(ClassName.OPEN)
313         this._resetAdjustments()
314         this._resetScrollbar()
315         $(this._element).trigger(Event.HIDDEN)
316       })
317     }
318
319     _removeBackdrop() {
320       if (this._backdrop) {
321         $(this._backdrop).remove()
322         this._backdrop = null
323       }
324     }
325
326     _showBackdrop(callback) {
327       const animate = $(this._element).hasClass(ClassName.FADE)
328         ? ClassName.FADE : ''
329
330       if (this._isShown && this._config.backdrop) {
331         this._backdrop = document.createElement('div')
332         this._backdrop.className = ClassName.BACKDROP
333
334         if (animate) {
335           this._backdrop.classList.add(animate)
336         }
337
338         $(this._backdrop).appendTo(document.body)
339
340         $(this._element).on(Event.CLICK_DISMISS, (event) => {
341           if (this._ignoreBackdropClick) {
342             this._ignoreBackdropClick = false
343             return
344           }
345           if (event.target !== event.currentTarget) {
346             return
347           }
348           if (this._config.backdrop === 'static') {
349             this._element.focus()
350           } else {
351             this.hide()
352           }
353         })
354
355         if (animate) {
356           Util.reflow(this._backdrop)
357         }
358
359         $(this._backdrop).addClass(ClassName.SHOW)
360
361         if (!callback) {
362           return
363         }
364
365         if (!animate) {
366           callback()
367           return
368         }
369
370         const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
371
372         $(this._backdrop)
373           .one(Util.TRANSITION_END, callback)
374           .emulateTransitionEnd(backdropTransitionDuration)
375       } else if (!this._isShown && this._backdrop) {
376         $(this._backdrop).removeClass(ClassName.SHOW)
377
378         const callbackRemove = () => {
379           this._removeBackdrop()
380           if (callback) {
381             callback()
382           }
383         }
384
385         if ($(this._element).hasClass(ClassName.FADE)) {
386           const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
387
388           $(this._backdrop)
389             .one(Util.TRANSITION_END, callbackRemove)
390             .emulateTransitionEnd(backdropTransitionDuration)
391         } else {
392           callbackRemove()
393         }
394       } else if (callback) {
395         callback()
396       }
397     }
398
399     // ----------------------------------------------------------------------
400     // the following methods are used to handle overflowing modals
401     // todo (fat): these should probably be refactored out of modal.js
402     // ----------------------------------------------------------------------
403
404     _adjustDialog() {
405       const isModalOverflowing =
406         this._element.scrollHeight > document.documentElement.clientHeight
407
408       if (!this._isBodyOverflowing && isModalOverflowing) {
409         this._element.style.paddingLeft = `${this._scrollbarWidth}px`
410       }
411
412       if (this._isBodyOverflowing && !isModalOverflowing) {
413         this._element.style.paddingRight = `${this._scrollbarWidth}px`
414       }
415     }
416
417     _resetAdjustments() {
418       this._element.style.paddingLeft = ''
419       this._element.style.paddingRight = ''
420     }
421
422     _checkScrollbar() {
423       const rect = document.body.getBoundingClientRect()
424       this._isBodyOverflowing = rect.left + rect.right < window.innerWidth
425       this._scrollbarWidth = this._getScrollbarWidth()
426     }
427
428     _setScrollbar() {
429       if (this._isBodyOverflowing) {
430         // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
431         //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
432         const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))
433         const stickyContent = [].slice.call(document.querySelectorAll(Selector.STICKY_CONTENT))
434
435         // Adjust fixed content padding
436         $(fixedContent).each((index, element) => {
437           const actualPadding = element.style.paddingRight
438           const calculatedPadding = $(element).css('padding-right')
439           $(element)
440             .data('padding-right', actualPadding)
441             .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
442         })
443
444         // Adjust sticky content margin
445         $(stickyContent).each((index, element) => {
446           const actualMargin = element.style.marginRight
447           const calculatedMargin = $(element).css('margin-right')
448           $(element)
449             .data('margin-right', actualMargin)
450             .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)
451         })
452
453         // Adjust body padding
454         const actualPadding = document.body.style.paddingRight
455         const calculatedPadding = $(document.body).css('padding-right')
456         $(document.body)
457           .data('padding-right', actualPadding)
458           .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
459       }
460     }
461
462     _resetScrollbar() {
463       // Restore fixed content padding
464       const fixedContent = [].slice.call(document.querySelectorAll(Selector.FIXED_CONTENT))
465       $(fixedContent).each((index, element) => {
466         const padding = $(element).data('padding-right')
467         $(element).removeData('padding-right')
468         element.style.paddingRight = padding ? padding : ''
469       })
470
471       // Restore sticky content
472       const elements = [].slice.call(document.querySelectorAll(`${Selector.STICKY_CONTENT}`))
473       $(elements).each((index, element) => {
474         const margin = $(element).data('margin-right')
475         if (typeof margin !== 'undefined') {
476           $(element).css('margin-right', margin).removeData('margin-right')
477         }
478       })
479
480       // Restore body padding
481       const padding = $(document.body).data('padding-right')
482       $(document.body).removeData('padding-right')
483       document.body.style.paddingRight = padding ? padding : ''
484     }
485
486     _getScrollbarWidth() { // thx d.walsh
487       const scrollDiv = document.createElement('div')
488       scrollDiv.className = ClassName.SCROLLBAR_MEASURER
489       document.body.appendChild(scrollDiv)
490       const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
491       document.body.removeChild(scrollDiv)
492       return scrollbarWidth
493     }
494
495     // Static
496
497     static _jQueryInterface(config, relatedTarget) {
498       return this.each(function () {
499         let data = $(this).data(DATA_KEY)
500         const _config = {
501           ...Default,
502           ...$(this).data(),
503           ...typeof config === 'object' && config ? config : {}
504         }
505
506         if (!data) {
507           data = new Modal(this, _config)
508           $(this).data(DATA_KEY, data)
509         }
510
511         if (typeof config === 'string') {
512           if (typeof data[config] === 'undefined') {
513             throw new TypeError(`No method named "${config}"`)
514           }
515           data[config](relatedTarget)
516         } else if (_config.show) {
517           data.show(relatedTarget)
518         }
519       })
520     }
521   }
522
523   /**
524    * ------------------------------------------------------------------------
525    * Data Api implementation
526    * ------------------------------------------------------------------------
527    */
528
529   $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
530     let target
531     const selector = Util.getSelectorFromElement(this)
532
533     if (selector) {
534       target = document.querySelector(selector)
535     }
536
537     const config = $(target).data(DATA_KEY)
538       ? 'toggle' : {
539         ...$(target).data(),
540         ...$(this).data()
541       }
542
543     if (this.tagName === 'A' || this.tagName === 'AREA') {
544       event.preventDefault()
545     }
546
547     const $target = $(target).one(Event.SHOW, (showEvent) => {
548       if (showEvent.isDefaultPrevented()) {
549         // Only register focus restorer if modal will actually get shown
550         return
551       }
552
553       $target.one(Event.HIDDEN, () => {
554         if ($(this).is(':visible')) {
555           this.focus()
556         }
557       })
558     })
559
560     Modal._jQueryInterface.call($(target), config, this)
561   })
562
563   /**
564    * ------------------------------------------------------------------------
565    * jQuery
566    * ------------------------------------------------------------------------
567    */
568
569   $.fn[NAME] = Modal._jQueryInterface
570   $.fn[NAME].Constructor = Modal
571   $.fn[NAME].noConflict = function () {
572     $.fn[NAME] = JQUERY_NO_CONFLICT
573     return Modal._jQueryInterface
574   }
575
576   return Modal
577 })($)
578
579 export default Modal