2018-11-13 07:41:12 +01:00
/ * !
2021-05-13 18:22:20 +02:00
* Bootstrap modal . js v5 . 0.1 ( https : //getbootstrap.com/)
2021-02-10 17:14:51 +01:00
* Copyright 2011 - 2021 The Bootstrap Authors ( https : //github.com/twbs/bootstrap/graphs/contributors)
2020-06-16 20:50:01 +02:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
2018-11-13 07:41:12 +01:00
* /
2018-07-24 02:51:14 +02:00
( function ( global , factory ) {
2021-05-13 18:22:20 +02:00
typeof exports === 'object' && typeof module !== 'undefined' ? module . exports = factory ( require ( './dom/selector-engine.js' ) , require ( './dom/event-handler.js' ) , require ( './dom/manipulator.js' ) , require ( './base-component.js' ) ) :
typeof define === 'function' && define . amd ? define ( [ './dom/selector-engine' , './dom/event-handler' , './dom/manipulator' , './base-component' ] , factory ) :
( global = typeof globalThis !== 'undefined' ? globalThis : global || self , global . Modal = factory ( global . SelectorEngine , global . EventHandler , global . Manipulator , global . Base ) ) ;
} ( this , ( function ( SelectorEngine , EventHandler , Manipulator , BaseComponent ) { 'use strict' ;
2018-07-24 02:51:14 +02:00
2020-09-14 17:12:06 +02:00
function _interopDefaultLegacy ( e ) { return e && typeof e === 'object' && 'default' in e ? e : { 'default' : e } ; }
2021-05-13 18:22:20 +02:00
var SelectorEngine _ _default = /*#__PURE__*/ _interopDefaultLegacy ( SelectorEngine ) ;
2020-09-14 17:12:06 +02:00
var EventHandler _ _default = /*#__PURE__*/ _interopDefaultLegacy ( EventHandler ) ;
var Manipulator _ _default = /*#__PURE__*/ _interopDefaultLegacy ( Manipulator ) ;
2021-02-10 17:14:51 +01:00
var BaseComponent _ _default = /*#__PURE__*/ _interopDefaultLegacy ( BaseComponent ) ;
2021-03-23 17:26:54 +01:00
const MILLISECONDS _MULTIPLIER = 1000 ;
const TRANSITION _END = 'transitionend' ; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
2019-03-01 17:31:34 +01:00
2021-03-23 17:26:54 +01:00
const toType = obj => {
2020-03-28 11:29:08 +01:00
if ( obj === null || obj === undefined ) {
2021-03-23 17:26:54 +01:00
return ` ${ obj } ` ;
2020-03-28 11:29:08 +01:00
}
2019-03-01 17:31:34 +01:00
return { } . toString . call ( obj ) . match ( /\s([a-z]+)/i ) [ 1 ] . toLowerCase ( ) ;
} ;
2021-03-23 17:26:54 +01:00
const getSelector = element => {
let selector = element . getAttribute ( 'data-bs-target' ) ;
2019-03-01 17:31:34 +01:00
if ( ! selector || selector === '#' ) {
2021-03-23 17:26:54 +01:00
let hrefAttr = element . getAttribute ( 'href' ) ; // The only valid content that could double as a selector are IDs or classes,
2021-02-10 17:14:51 +01:00
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
// `document.querySelector` will rightfully complain it is invalid.
// See https://github.com/twbs/bootstrap/issues/32273
if ( ! hrefAttr || ! hrefAttr . includes ( '#' ) && ! hrefAttr . startsWith ( '.' ) ) {
return null ;
} // Just in case some CMS puts out a full URL with the anchor appended
if ( hrefAttr . includes ( '#' ) && ! hrefAttr . startsWith ( '#' ) ) {
2021-05-05 21:32:12 +02:00
hrefAttr = ` # ${ hrefAttr . split ( '#' ) [ 1 ] } ` ;
2021-02-10 17:14:51 +01:00
}
2019-08-27 15:03:21 +02:00
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr . trim ( ) : null ;
2019-03-01 17:31:34 +01:00
}
2019-08-27 15:03:21 +02:00
return selector ;
} ;
2021-03-23 17:26:54 +01:00
const getElementFromSelector = element => {
const selector = getSelector ( element ) ;
2019-08-27 15:03:21 +02:00
return selector ? document . querySelector ( selector ) : null ;
2019-03-01 17:31:34 +01:00
} ;
2021-03-23 17:26:54 +01:00
const getTransitionDurationFromElement = element => {
2019-03-01 17:31:34 +01:00
if ( ! element ) {
return 0 ;
} // Get transition-duration of the element
2021-03-23 17:26:54 +01:00
let {
transitionDuration ,
transitionDelay
} = window . getComputedStyle ( element ) ;
const floatTransitionDuration = Number . parseFloat ( transitionDuration ) ;
const floatTransitionDelay = Number . parseFloat ( transitionDelay ) ; // Return 0 if element or transition duration is not found
2019-03-01 17:31:34 +01:00
if ( ! floatTransitionDuration && ! floatTransitionDelay ) {
return 0 ;
} // If multiple durations are defined, take the first
transitionDuration = transitionDuration . split ( ',' ) [ 0 ] ;
transitionDelay = transitionDelay . split ( ',' ) [ 0 ] ;
2020-11-23 14:17:16 +01:00
return ( Number . parseFloat ( transitionDuration ) + Number . parseFloat ( transitionDelay ) ) * MILLISECONDS _MULTIPLIER ;
2019-03-01 17:31:34 +01:00
} ;
2021-03-23 17:26:54 +01:00
const triggerTransitionEnd = element => {
2020-03-28 11:29:08 +01:00
element . dispatchEvent ( new Event ( TRANSITION _END ) ) ;
2019-03-01 17:31:34 +01:00
} ;
2021-05-13 18:22:20 +02:00
const isElement = obj => {
if ( ! obj || typeof obj !== 'object' ) {
return false ;
}
if ( typeof obj . jquery !== 'undefined' ) {
obj = obj [ 0 ] ;
}
return typeof obj . nodeType !== 'undefined' ;
} ;
2019-03-01 17:31:34 +01:00
2021-03-23 17:26:54 +01:00
const emulateTransitionEnd = ( element , duration ) => {
let called = false ;
const durationPadding = 5 ;
const emulatedDuration = duration + durationPadding ;
2019-03-01 17:31:34 +01:00
function listener ( ) {
called = true ;
element . removeEventListener ( TRANSITION _END , listener ) ;
}
element . addEventListener ( TRANSITION _END , listener ) ;
2021-03-23 17:26:54 +01:00
setTimeout ( ( ) => {
2019-03-01 17:31:34 +01:00
if ( ! called ) {
triggerTransitionEnd ( element ) ;
}
} , emulatedDuration ) ;
} ;
2021-03-23 17:26:54 +01:00
const typeCheckConfig = ( componentName , config , configTypes ) => {
Object . keys ( configTypes ) . forEach ( property => {
const expectedTypes = configTypes [ property ] ;
const value = config [ property ] ;
const valueType = value && isElement ( value ) ? 'element' : toType ( value ) ;
2019-03-01 17:31:34 +01:00
if ( ! new RegExp ( expectedTypes ) . test ( valueType ) ) {
2021-05-05 21:32:12 +02:00
throw new TypeError ( ` ${ componentName . toUpperCase ( ) } : Option " ${ property } " provided type " ${ valueType } " but expected type " ${ expectedTypes } ". ` ) ;
2019-03-01 17:31:34 +01:00
}
} ) ;
} ;
2021-03-23 17:26:54 +01:00
const isVisible = element => {
2019-03-01 17:31:34 +01:00
if ( ! element ) {
return false ;
}
if ( element . style && element . parentNode && element . parentNode . style ) {
2021-03-23 17:26:54 +01:00
const elementStyle = getComputedStyle ( element ) ;
const parentNodeStyle = getComputedStyle ( element . parentNode ) ;
2019-11-08 09:11:23 +01:00
return elementStyle . display !== 'none' && parentNodeStyle . display !== 'none' && elementStyle . visibility !== 'hidden' ;
2019-03-01 17:31:34 +01:00
}
return false ;
} ;
2021-03-23 17:26:54 +01:00
const reflow = element => element . offsetHeight ;
2019-03-01 17:31:34 +01:00
2021-03-23 17:26:54 +01:00
const getjQuery = ( ) => {
const {
jQuery
} = window ;
2019-08-27 15:03:21 +02:00
2020-11-23 14:17:16 +01:00
if ( jQuery && ! document . body . hasAttribute ( 'data-bs-no-jquery' ) ) {
2019-08-27 15:03:21 +02:00
return jQuery ;
}
return null ;
} ;
2021-03-23 17:26:54 +01:00
const onDOMContentLoaded = callback => {
2020-11-11 18:07:37 +01:00
if ( document . readyState === 'loading' ) {
document . addEventListener ( 'DOMContentLoaded' , callback ) ;
} else {
callback ( ) ;
}
} ;
2021-03-23 17:26:54 +01:00
const isRTL = ( ) => document . documentElement . dir === 'rtl' ;
2020-12-03 14:08:31 +01:00
2021-05-13 18:22:20 +02:00
const defineJQueryPlugin = plugin => {
2021-03-23 17:26:54 +01:00
onDOMContentLoaded ( ( ) => {
const $ = getjQuery ( ) ;
2021-02-10 17:14:51 +01:00
/* istanbul ignore if */
2020-12-03 15:18:59 +01:00
2021-02-10 17:14:51 +01:00
if ( $ ) {
2021-05-13 18:22:20 +02:00
const name = plugin . NAME ;
2021-03-23 17:26:54 +01:00
const JQUERY _NO _CONFLICT = $ . fn [ name ] ;
2021-02-10 17:14:51 +01:00
$ . fn [ name ] = plugin . jQueryInterface ;
$ . fn [ name ] . Constructor = plugin ;
2020-12-03 15:18:59 +01:00
2021-03-23 17:26:54 +01:00
$ . fn [ name ] . noConflict = ( ) => {
2021-02-10 17:14:51 +01:00
$ . fn [ name ] = JQUERY _NO _CONFLICT ;
return plugin . jQueryInterface ;
} ;
2020-12-03 15:18:59 +01:00
}
2021-02-10 17:14:51 +01:00
} ) ;
} ;
2020-12-03 15:18:59 +01:00
2021-05-05 21:32:12 +02:00
const execute = callback => {
if ( typeof callback === 'function' ) {
callback ( ) ;
}
} ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-05-13 18:22:20 +02:00
* Bootstrap ( v5 . 0.1 ) : util / scrollBar . js
2021-05-05 21:32:12 +02:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const SELECTOR _FIXED _CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' ;
const SELECTOR _STICKY _CONTENT = '.sticky-top' ;
const getWidth = ( ) => {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
const documentWidth = document . documentElement . clientWidth ;
return Math . abs ( window . innerWidth - documentWidth ) ;
} ;
const hide = ( width = getWidth ( ) ) => {
_disableOverFlow ( ) ; // give padding to element to balances the hidden scrollbar width
_setElementAttributes ( 'body' , 'paddingRight' , calculatedValue => calculatedValue + width ) ; // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
_setElementAttributes ( SELECTOR _FIXED _CONTENT , 'paddingRight' , calculatedValue => calculatedValue + width ) ;
_setElementAttributes ( SELECTOR _STICKY _CONTENT , 'marginRight' , calculatedValue => calculatedValue - width ) ;
} ;
const _disableOverFlow = ( ) => {
const actualValue = document . body . style . overflow ;
if ( actualValue ) {
Manipulator _ _default [ 'default' ] . setDataAttribute ( document . body , 'overflow' , actualValue ) ;
}
document . body . style . overflow = 'hidden' ;
} ;
const _setElementAttributes = ( selector , styleProp , callback ) => {
const scrollbarWidth = getWidth ( ) ;
SelectorEngine _ _default [ 'default' ] . find ( selector ) . forEach ( element => {
if ( element !== document . body && window . innerWidth > element . clientWidth + scrollbarWidth ) {
return ;
}
const actualValue = element . style [ styleProp ] ;
const calculatedValue = window . getComputedStyle ( element ) [ styleProp ] ;
Manipulator _ _default [ 'default' ] . setDataAttribute ( element , styleProp , actualValue ) ;
element . style [ styleProp ] = ` ${ callback ( Number . parseFloat ( calculatedValue ) ) } px ` ;
} ) ;
} ;
const reset = ( ) => {
_resetElementAttributes ( 'body' , 'overflow' ) ;
_resetElementAttributes ( 'body' , 'paddingRight' ) ;
_resetElementAttributes ( SELECTOR _FIXED _CONTENT , 'paddingRight' ) ;
_resetElementAttributes ( SELECTOR _STICKY _CONTENT , 'marginRight' ) ;
} ;
const _resetElementAttributes = ( selector , styleProp ) => {
SelectorEngine _ _default [ 'default' ] . find ( selector ) . forEach ( element => {
const value = Manipulator _ _default [ 'default' ] . getDataAttribute ( element , styleProp ) ;
if ( typeof value === 'undefined' ) {
element . style . removeProperty ( styleProp ) ;
} else {
Manipulator _ _default [ 'default' ] . removeDataAttribute ( element , styleProp ) ;
element . style [ styleProp ] = value ;
}
} ) ;
} ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-05-13 18:22:20 +02:00
* Bootstrap ( v5 . 0.1 ) : util / backdrop . js
2021-05-05 21:32:12 +02:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/master/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const Default$1 = {
isVisible : true ,
// if false, we use the backdrop helper without adding any element to the dom
isAnimated : false ,
rootElement : document . body ,
// give the choice to place backdrop under different elements
clickCallback : null
} ;
const DefaultType$1 = {
isVisible : 'boolean' ,
isAnimated : 'boolean' ,
rootElement : 'element' ,
clickCallback : '(function|null)'
} ;
const NAME$1 = 'backdrop' ;
const CLASS _NAME _BACKDROP = 'modal-backdrop' ;
const CLASS _NAME _FADE$1 = 'fade' ;
const CLASS _NAME _SHOW$1 = 'show' ;
const EVENT _MOUSEDOWN = ` mousedown.bs. ${ NAME$1 } ` ;
class Backdrop {
constructor ( config ) {
this . _config = this . _getConfig ( config ) ;
this . _isAppended = false ;
this . _element = null ;
}
show ( callback ) {
if ( ! this . _config . isVisible ) {
execute ( callback ) ;
return ;
}
this . _append ( ) ;
if ( this . _config . isAnimated ) {
reflow ( this . _getElement ( ) ) ;
}
this . _getElement ( ) . classList . add ( CLASS _NAME _SHOW$1 ) ;
this . _emulateAnimation ( ( ) => {
execute ( callback ) ;
} ) ;
}
hide ( callback ) {
if ( ! this . _config . isVisible ) {
execute ( callback ) ;
return ;
}
this . _getElement ( ) . classList . remove ( CLASS _NAME _SHOW$1 ) ;
this . _emulateAnimation ( ( ) => {
this . dispose ( ) ;
execute ( callback ) ;
} ) ;
} // Private
_getElement ( ) {
if ( ! this . _element ) {
const backdrop = document . createElement ( 'div' ) ;
backdrop . className = CLASS _NAME _BACKDROP ;
if ( this . _config . isAnimated ) {
backdrop . classList . add ( CLASS _NAME _FADE$1 ) ;
}
this . _element = backdrop ;
}
return this . _element ;
}
_getConfig ( config ) {
config = { ... Default$1 ,
... ( typeof config === 'object' ? config : { } )
} ;
2021-05-13 18:22:20 +02:00
config . rootElement = config . rootElement || document . body ;
2021-05-05 21:32:12 +02:00
typeCheckConfig ( NAME$1 , config , DefaultType$1 ) ;
return config ;
}
_append ( ) {
if ( this . _isAppended ) {
return ;
}
this . _config . rootElement . appendChild ( this . _getElement ( ) ) ;
EventHandler _ _default [ 'default' ] . on ( this . _getElement ( ) , EVENT _MOUSEDOWN , ( ) => {
execute ( this . _config . clickCallback ) ;
} ) ;
this . _isAppended = true ;
}
dispose ( ) {
if ( ! this . _isAppended ) {
return ;
}
EventHandler _ _default [ 'default' ] . off ( this . _element , EVENT _MOUSEDOWN ) ;
this . _getElement ( ) . parentNode . removeChild ( this . _element ) ;
this . _isAppended = false ;
}
_emulateAnimation ( callback ) {
if ( ! this . _config . isAnimated ) {
execute ( callback ) ;
return ;
}
const backdropTransitionDuration = getTransitionDurationFromElement ( this . _getElement ( ) ) ;
EventHandler _ _default [ 'default' ] . one ( this . _getElement ( ) , 'transitionend' , ( ) => execute ( callback ) ) ;
emulateTransitionEnd ( this . _getElement ( ) , backdropTransitionDuration ) ;
}
}
2021-03-23 17:26:54 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-05-13 18:22:20 +02:00
* Bootstrap ( v5 . 0.1 ) : modal . js
2021-03-23 17:26:54 +01:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2020-12-03 15:18:59 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Constants
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-03-23 17:26:54 +01:00
const NAME = 'modal' ;
const DATA _KEY = 'bs.modal' ;
const EVENT _KEY = ` . ${ DATA _KEY } ` ;
const DATA _API _KEY = '.data-api' ;
const ESCAPE _KEY = 'Escape' ;
const Default = {
2018-11-13 07:41:12 +01:00
backdrop : true ,
keyboard : true ,
2020-12-03 15:18:59 +01:00
focus : true
2018-11-13 07:41:12 +01:00
} ;
2021-03-23 17:26:54 +01:00
const DefaultType = {
2018-11-13 07:41:12 +01:00
backdrop : '(boolean|string)' ,
keyboard : 'boolean' ,
2020-12-03 15:18:59 +01:00
focus : 'boolean'
2018-11-13 07:41:12 +01:00
} ;
2021-03-23 17:26:54 +01:00
const EVENT _HIDE = ` hide ${ EVENT _KEY } ` ;
const EVENT _HIDE _PREVENTED = ` hidePrevented ${ EVENT _KEY } ` ;
const EVENT _HIDDEN = ` hidden ${ EVENT _KEY } ` ;
const EVENT _SHOW = ` show ${ EVENT _KEY } ` ;
const EVENT _SHOWN = ` shown ${ EVENT _KEY } ` ;
const EVENT _FOCUSIN = ` focusin ${ EVENT _KEY } ` ;
const EVENT _RESIZE = ` resize ${ EVENT _KEY } ` ;
const EVENT _CLICK _DISMISS = ` click.dismiss ${ EVENT _KEY } ` ;
const EVENT _KEYDOWN _DISMISS = ` keydown.dismiss ${ EVENT _KEY } ` ;
const EVENT _MOUSEUP _DISMISS = ` mouseup.dismiss ${ EVENT _KEY } ` ;
const EVENT _MOUSEDOWN _DISMISS = ` mousedown.dismiss ${ EVENT _KEY } ` ;
const EVENT _CLICK _DATA _API = ` click ${ EVENT _KEY } ${ DATA _API _KEY } ` ;
const CLASS _NAME _OPEN = 'modal-open' ;
const CLASS _NAME _FADE = 'fade' ;
const CLASS _NAME _SHOW = 'show' ;
const CLASS _NAME _STATIC = 'modal-static' ;
const SELECTOR _DIALOG = '.modal-dialog' ;
const SELECTOR _MODAL _BODY = '.modal-body' ;
const SELECTOR _DATA _TOGGLE = '[data-bs-toggle="modal"]' ;
const SELECTOR _DATA _DISMISS = '[data-bs-dismiss="modal"]' ;
2019-10-08 08:39:10 +02:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Class Definition
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2018-11-13 07:41:12 +01:00
2021-03-23 17:26:54 +01:00
class Modal extends BaseComponent _ _default [ 'default' ] {
constructor ( element , config ) {
super ( element ) ;
this . _config = this . _getConfig ( config ) ;
this . _dialog = SelectorEngine _ _default [ 'default' ] . findOne ( SELECTOR _DIALOG , this . _element ) ;
2021-05-05 21:32:12 +02:00
this . _backdrop = this . _initializeBackDrop ( ) ;
2021-03-23 17:26:54 +01:00
this . _isShown = false ;
this . _ignoreBackdropClick = false ;
this . _isTransitioning = false ;
2018-11-13 07:41:12 +01:00
} // Getters
2021-03-23 17:26:54 +01:00
static get Default ( ) {
return Default ;
}
2018-11-13 07:41:12 +01:00
2021-05-13 18:22:20 +02:00
static get NAME ( ) {
return NAME ;
2021-03-23 17:26:54 +01:00
} // Public
2015-05-11 04:45:38 +02:00
2015-08-13 06:12:03 +02:00
2021-03-23 17:26:54 +01:00
toggle ( relatedTarget ) {
return this . _isShown ? this . hide ( ) : this . show ( relatedTarget ) ;
}
show ( relatedTarget ) {
2018-11-13 07:41:12 +01:00
if ( this . _isShown || this . _isTransitioning ) {
return ;
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
if ( this . _isAnimated ( ) ) {
2018-11-13 07:41:12 +01:00
this . _isTransitioning = true ;
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
const showEvent = EventHandler _ _default [ 'default' ] . trigger ( this . _element , EVENT _SHOW , {
relatedTarget
2018-11-13 07:41:12 +01:00
} ) ;
2016-10-10 02:26:51 +02:00
2019-03-01 17:31:34 +01:00
if ( this . _isShown || showEvent . defaultPrevented ) {
2018-11-13 07:41:12 +01:00
return ;
}
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
this . _isShown = true ;
2021-05-05 21:32:12 +02:00
hide ( ) ;
document . body . classList . add ( CLASS _NAME _OPEN ) ;
2016-12-02 19:13:36 +01:00
2018-11-13 07:41:12 +01:00
this . _adjustDialog ( ) ;
2017-04-02 04:18:29 +02:00
2018-11-13 07:41:12 +01:00
this . _setEscapeEvent ( ) ;
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
this . _setResizeEvent ( ) ;
2017-04-02 04:18:29 +02:00
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . on ( this . _element , EVENT _CLICK _DISMISS , SELECTOR _DATA _DISMISS , event => this . hide ( event ) ) ;
EventHandler _ _default [ 'default' ] . on ( this . _dialog , EVENT _MOUSEDOWN _DISMISS , ( ) => {
EventHandler _ _default [ 'default' ] . one ( this . _element , EVENT _MOUSEUP _DISMISS , event => {
if ( event . target === this . _element ) {
this . _ignoreBackdropClick = true ;
2018-11-13 07:41:12 +01:00
}
2018-07-24 02:51:14 +02:00
} ) ;
2018-11-13 07:41:12 +01:00
} ) ;
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
this . _showBackdrop ( ( ) => this . _showElement ( relatedTarget ) ) ;
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
hide ( event ) {
2018-11-13 07:41:12 +01:00
if ( event ) {
event . preventDefault ( ) ;
}
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
if ( ! this . _isShown || this . _isTransitioning ) {
return ;
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
const hideEvent = EventHandler _ _default [ 'default' ] . trigger ( this . _element , EVENT _HIDE ) ;
2015-05-11 04:45:38 +02:00
2019-07-24 08:13:50 +02:00
if ( hideEvent . defaultPrevented ) {
2018-11-13 07:41:12 +01:00
return ;
}
2017-10-16 00:51:44 +02:00
2018-11-13 07:41:12 +01:00
this . _isShown = false ;
2019-03-01 17:31:34 +01:00
2021-03-23 17:26:54 +01:00
const isAnimated = this . _isAnimated ( ) ;
2017-04-02 04:18:29 +02:00
2021-03-23 17:26:54 +01:00
if ( isAnimated ) {
2018-11-13 07:41:12 +01:00
this . _isTransitioning = true ;
}
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
this . _setEscapeEvent ( ) ;
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
this . _setResizeEvent ( ) ;
2016-10-10 02:26:51 +02:00
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( document , EVENT _FOCUSIN ) ;
2019-03-01 17:31:34 +01:00
2020-03-28 11:29:08 +01:00
this . _element . classList . remove ( CLASS _NAME _SHOW ) ;
2019-03-01 17:31:34 +01:00
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( this . _element , EVENT _CLICK _DISMISS ) ;
EventHandler _ _default [ 'default' ] . off ( this . _dialog , EVENT _MOUSEDOWN _DISMISS ) ;
2017-09-30 23:28:03 +02:00
2021-05-13 18:22:20 +02:00
this . _queueCallback ( ( ) => this . _hideModal ( ) , this . _element , isAnimated ) ;
2021-03-23 17:26:54 +01:00
}
2020-12-03 15:18:59 +01:00
2021-03-23 17:26:54 +01:00
dispose ( ) {
2021-05-05 21:32:12 +02:00
[ window , this . _dialog ] . forEach ( htmlElement => EventHandler _ _default [ 'default' ] . off ( htmlElement , EVENT _KEY ) ) ;
2021-05-13 18:22:20 +02:00
this . _backdrop . dispose ( ) ;
2021-03-23 17:26:54 +01:00
super . dispose ( ) ;
2018-11-13 07:41:12 +01:00
/ * *
2020-03-28 11:29:08 +01:00
* ` document ` has 2 events ` EVENT_FOCUSIN ` and ` EVENT_CLICK_DATA_API `
2018-11-13 07:41:12 +01:00
* Do not move ` document ` in ` htmlElements ` array
2020-03-28 11:29:08 +01:00
* It will remove ` EVENT_CLICK_DATA_API ` event that should remain
2018-11-13 07:41:12 +01:00
* /
2017-03-26 20:26:31 +02:00
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( document , EVENT _FOCUSIN ) ;
2021-03-23 17:26:54 +01:00
}
2016-10-10 02:26:51 +02:00
2021-03-23 17:26:54 +01:00
handleUpdate ( ) {
2018-11-13 07:41:12 +01:00
this . _adjustDialog ( ) ;
2019-01-04 17:29:45 +01:00
} // Private
2016-10-10 02:26:51 +02:00
2021-03-23 17:26:54 +01:00
2021-05-05 21:32:12 +02:00
_initializeBackDrop ( ) {
return new Backdrop ( {
isVisible : Boolean ( this . _config . backdrop ) ,
// 'static' option will be translated to true, and booleans will keep their value
isAnimated : this . _isAnimated ( )
} ) ;
}
2021-03-23 17:26:54 +01:00
_getConfig ( config ) {
config = { ... Default ,
2021-05-05 21:32:12 +02:00
... Manipulator _ _default [ 'default' ] . getDataAttributes ( this . _element ) ,
2021-03-23 17:26:54 +01:00
... config
} ;
2019-03-01 17:31:34 +01:00
typeCheckConfig ( NAME , config , DefaultType ) ;
2018-11-13 07:41:12 +01:00
return config ;
2021-03-23 17:26:54 +01:00
}
2017-09-30 23:28:03 +02:00
2021-03-23 17:26:54 +01:00
_showElement ( relatedTarget ) {
const isAnimated = this . _isAnimated ( ) ;
2017-09-30 23:28:03 +02:00
2021-03-23 17:26:54 +01:00
const modalBody = SelectorEngine _ _default [ 'default' ] . findOne ( SELECTOR _MODAL _BODY , this . _dialog ) ;
2019-08-27 15:03:21 +02:00
2018-11-13 07:41:12 +01:00
if ( ! this . _element . parentNode || this . _element . parentNode . nodeType !== Node . ELEMENT _NODE ) {
// Don't move modal's DOM position
document . body . appendChild ( this . _element ) ;
}
2017-09-30 23:28:03 +02:00
2018-11-13 07:41:12 +01:00
this . _element . style . display = 'block' ;
2017-09-30 23:28:03 +02:00
2018-11-13 07:41:12 +01:00
this . _element . removeAttribute ( 'aria-hidden' ) ;
2015-05-11 04:45:38 +02:00
2018-12-16 00:13:22 +01:00
this . _element . setAttribute ( 'aria-modal' , true ) ;
2020-06-14 00:40:28 +02:00
this . _element . setAttribute ( 'role' , 'dialog' ) ;
2020-05-13 20:53:43 +02:00
this . _element . scrollTop = 0 ;
if ( modalBody ) {
2019-08-27 15:03:21 +02:00
modalBody . scrollTop = 0 ;
2019-02-11 20:15:34 +01:00
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
if ( isAnimated ) {
2019-03-01 17:31:34 +01:00
reflow ( this . _element ) ;
2018-11-13 07:41:12 +01:00
}
2015-05-11 04:45:38 +02:00
2020-03-28 11:29:08 +01:00
this . _element . classList . add ( CLASS _NAME _SHOW ) ;
2018-07-24 02:51:14 +02:00
2018-11-13 07:41:12 +01:00
if ( this . _config . focus ) {
this . _enforceFocus ( ) ;
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
const transitionComplete = ( ) => {
if ( this . _config . focus ) {
this . _element . focus ( ) ;
2017-09-06 06:05:12 +02:00
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
this . _isTransitioning = false ;
EventHandler _ _default [ 'default' ] . trigger ( this . _element , EVENT _SHOWN , {
relatedTarget
2019-03-01 17:31:34 +01:00
} ) ;
2017-09-30 23:28:03 +02:00
} ;
2015-05-11 04:45:38 +02:00
2021-05-13 18:22:20 +02:00
this . _queueCallback ( transitionComplete , this . _dialog , isAnimated ) ;
2021-03-23 17:26:54 +01:00
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
_enforceFocus ( ) {
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( document , EVENT _FOCUSIN ) ; // guard against infinite focus loop
2019-03-01 17:31:34 +01:00
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . on ( document , EVENT _FOCUSIN , event => {
if ( document !== event . target && this . _element !== event . target && ! this . _element . contains ( event . target ) ) {
this . _element . focus ( ) ;
2015-05-11 04:45:38 +02:00
}
2018-11-13 07:41:12 +01:00
} ) ;
2021-03-23 17:26:54 +01:00
}
2016-10-10 02:26:51 +02:00
2021-03-23 17:26:54 +01:00
_setEscapeEvent ( ) {
2020-03-28 11:29:08 +01:00
if ( this . _isShown ) {
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . on ( this . _element , EVENT _KEYDOWN _DISMISS , event => {
if ( this . _config . keyboard && event . key === ESCAPE _KEY ) {
2020-03-28 11:29:08 +01:00
event . preventDefault ( ) ;
2021-03-23 17:26:54 +01:00
this . hide ( ) ;
} else if ( ! this . _config . keyboard && event . key === ESCAPE _KEY ) {
this . _triggerBackdropTransition ( ) ;
2018-11-13 07:41:12 +01:00
}
} ) ;
2019-07-24 08:13:50 +02:00
} else {
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( this . _element , EVENT _KEYDOWN _DISMISS ) ;
2018-11-13 07:41:12 +01:00
}
2021-03-23 17:26:54 +01:00
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
_setResizeEvent ( ) {
2018-11-13 07:41:12 +01:00
if ( this . _isShown ) {
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . on ( window , EVENT _RESIZE , ( ) => this . _adjustDialog ( ) ) ;
2018-11-13 07:41:12 +01:00
} else {
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . off ( window , EVENT _RESIZE ) ;
2018-11-13 07:41:12 +01:00
}
2021-03-23 17:26:54 +01:00
}
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
_hideModal ( ) {
2018-11-13 07:41:12 +01:00
this . _element . style . display = 'none' ;
2015-05-11 04:45:38 +02:00
2018-11-13 07:41:12 +01:00
this . _element . setAttribute ( 'aria-hidden' , true ) ;
2015-05-11 04:45:38 +02:00
2018-12-16 00:13:22 +01:00
this . _element . removeAttribute ( 'aria-modal' ) ;
2020-06-14 00:40:28 +02:00
this . _element . removeAttribute ( 'role' ) ;
2018-11-13 07:41:12 +01:00
this . _isTransitioning = false ;
2017-09-30 23:28:03 +02:00
2021-05-05 21:32:12 +02:00
this . _backdrop . hide ( ( ) => {
2020-03-28 11:29:08 +01:00
document . body . classList . remove ( CLASS _NAME _OPEN ) ;
2015-05-11 04:45:38 +02:00
2021-03-23 17:26:54 +01:00
this . _resetAdjustments ( ) ;
2017-09-30 23:28:03 +02:00
2021-05-05 21:32:12 +02:00
reset ( ) ;
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . trigger ( this . _element , EVENT _HIDDEN ) ;
2018-11-13 07:41:12 +01:00
} ) ;
2021-03-23 17:26:54 +01:00
}
2017-09-30 23:28:03 +02:00
2021-03-23 17:26:54 +01:00
_showBackdrop ( callback ) {
2021-05-05 21:32:12 +02:00
EventHandler _ _default [ 'default' ] . on ( this . _element , EVENT _CLICK _DISMISS , event => {
if ( this . _ignoreBackdropClick ) {
this . _ignoreBackdropClick = false ;
return ;
2018-11-13 07:41:12 +01:00
}
2015-05-11 04:45:38 +02:00
2021-05-05 21:32:12 +02:00
if ( event . target !== event . currentTarget ) {
2018-11-13 07:41:12 +01:00
return ;
2015-05-11 04:45:38 +02:00
}
2016-10-10 02:26:51 +02:00
2021-05-05 21:32:12 +02:00
if ( this . _config . backdrop === true ) {
this . hide ( ) ;
} else if ( this . _config . backdrop === 'static' ) {
this . _triggerBackdropTransition ( ) ;
2018-07-24 02:51:14 +02:00
}
2021-05-05 21:32:12 +02:00
} ) ;
this . _backdrop . show ( callback ) ;
2021-03-23 17:26:54 +01:00
}
2019-11-08 09:11:23 +01:00
2021-03-23 17:26:54 +01:00
_isAnimated ( ) {
return this . _element . classList . contains ( CLASS _NAME _FADE ) ;
}
2019-11-08 09:11:23 +01:00
2021-03-23 17:26:54 +01:00
_triggerBackdropTransition ( ) {
const hideEvent = EventHandler _ _default [ 'default' ] . trigger ( this . _element , EVENT _HIDE _PREVENTED ) ;
2019-11-08 09:11:23 +01:00
2020-11-23 14:17:16 +01:00
if ( hideEvent . defaultPrevented ) {
return ;
}
2019-11-08 09:11:23 +01:00
2021-03-23 17:26:54 +01:00
const isModalOverflowing = this . _element . scrollHeight > document . documentElement . clientHeight ;
2020-09-14 17:12:06 +02:00
2020-11-23 14:17:16 +01:00
if ( ! isModalOverflowing ) {
this . _element . style . overflowY = 'hidden' ;
}
2020-09-14 17:12:06 +02:00
2020-11-23 14:17:16 +01:00
this . _element . classList . add ( CLASS _NAME _STATIC ) ;
2019-11-08 09:11:23 +01:00
2021-03-23 17:26:54 +01:00
const modalTransitionDuration = getTransitionDurationFromElement ( this . _dialog ) ;
2021-02-10 17:14:51 +01:00
EventHandler _ _default [ 'default' ] . off ( this . _element , 'transitionend' ) ;
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . one ( this . _element , 'transitionend' , ( ) => {
this . _element . classList . remove ( CLASS _NAME _STATIC ) ;
2020-09-14 17:12:06 +02:00
2020-11-23 14:17:16 +01:00
if ( ! isModalOverflowing ) {
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . one ( this . _element , 'transitionend' , ( ) => {
this . _element . style . overflowY = '' ;
2020-11-23 14:17:16 +01:00
} ) ;
2021-03-23 17:26:54 +01:00
emulateTransitionEnd ( this . _element , modalTransitionDuration ) ;
2020-11-23 14:17:16 +01:00
}
} ) ;
emulateTransitionEnd ( this . _element , modalTransitionDuration ) ;
2019-11-08 09:11:23 +01:00
2020-11-23 14:17:16 +01:00
this . _element . focus ( ) ;
2019-01-04 17:29:45 +01:00
} // ----------------------------------------------------------------------
2018-11-13 07:41:12 +01:00
// the following methods are used to handle overflowing modals
// ----------------------------------------------------------------------
2017-09-30 23:28:03 +02:00
2021-03-23 17:26:54 +01:00
_adjustDialog ( ) {
const isModalOverflowing = this . _element . scrollHeight > document . documentElement . clientHeight ;
2021-05-05 21:32:12 +02:00
const scrollbarWidth = getWidth ( ) ;
const isBodyOverflowing = scrollbarWidth > 0 ;
2021-03-23 17:26:54 +01:00
2021-05-05 21:32:12 +02:00
if ( ! isBodyOverflowing && isModalOverflowing && ! isRTL ( ) || isBodyOverflowing && ! isModalOverflowing && isRTL ( ) ) {
this . _element . style . paddingLeft = ` ${ scrollbarWidth } px ` ;
2018-11-13 07:41:12 +01:00
}
2021-05-05 21:32:12 +02:00
if ( isBodyOverflowing && ! isModalOverflowing && ! isRTL ( ) || ! isBodyOverflowing && isModalOverflowing && isRTL ( ) ) {
this . _element . style . paddingRight = ` ${ scrollbarWidth } px ` ;
2018-11-13 07:41:12 +01:00
}
2021-03-23 17:26:54 +01:00
}
2018-11-13 07:41:12 +01:00
2021-03-23 17:26:54 +01:00
_resetAdjustments ( ) {
2018-11-13 07:41:12 +01:00
this . _element . style . paddingLeft = '' ;
this . _element . style . paddingRight = '' ;
2019-01-04 17:29:45 +01:00
} // Static
2016-10-10 02:26:51 +02:00
2021-03-23 17:26:54 +01:00
static jQueryInterface ( config , relatedTarget ) {
return this . each ( function ( ) {
2021-05-05 21:32:12 +02:00
const data = Modal . getInstance ( this ) || new Modal ( this , typeof config === 'object' ? config : { } ) ;
2017-09-30 23:28:03 +02:00
2021-05-05 21:32:12 +02:00
if ( typeof config !== 'string' ) {
return ;
2018-11-13 07:41:12 +01:00
}
2017-09-30 23:28:03 +02:00
2021-05-05 21:32:12 +02:00
if ( typeof data [ config ] === 'undefined' ) {
throw new TypeError ( ` No method named " ${ config } " ` ) ;
2018-07-24 02:51:14 +02:00
}
2021-05-05 21:32:12 +02:00
data [ config ] ( relatedTarget ) ;
2018-11-13 07:41:12 +01:00
} ) ;
2021-03-23 17:26:54 +01:00
}
2017-09-30 23:28:03 +02:00
2021-03-23 17:26:54 +01:00
}
2018-11-13 07:41:12 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Data Api implementation
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2015-05-11 04:45:38 +02:00
2020-09-14 17:12:06 +02:00
EventHandler _ _default [ 'default' ] . on ( document , EVENT _CLICK _DATA _API , SELECTOR _DATA _TOGGLE , function ( event ) {
2021-03-23 17:26:54 +01:00
const target = getElementFromSelector ( this ) ;
2018-11-13 07:41:12 +01:00
2021-05-05 21:32:12 +02:00
if ( [ 'A' , 'AREA' ] . includes ( this . tagName ) ) {
2018-11-13 07:41:12 +01:00
event . preventDefault ( ) ;
}
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . one ( target , EVENT _SHOW , showEvent => {
2019-03-01 17:31:34 +01:00
if ( showEvent . defaultPrevented ) {
// only register focus restorer if modal will actually get shown
2018-11-13 07:41:12 +01:00
return ;
2015-05-11 04:45:38 +02:00
}
2021-03-23 17:26:54 +01:00
EventHandler _ _default [ 'default' ] . one ( target , EVENT _HIDDEN , ( ) => {
if ( isVisible ( this ) ) {
this . focus ( ) ;
2015-05-11 04:45:38 +02:00
}
} ) ;
} ) ;
2021-05-05 21:32:12 +02:00
const data = Modal . getInstance ( target ) || new Modal ( target ) ;
2021-02-10 17:14:51 +01:00
data . toggle ( this ) ;
2018-11-13 07:41:12 +01:00
} ) ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* jQuery
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2020-11-11 18:07:37 +01:00
* add . Modal to jQuery only if jQuery is present
2018-11-13 07:41:12 +01:00
* /
2015-05-11 04:45:38 +02:00
2021-05-13 18:22:20 +02:00
defineJQueryPlugin ( Modal ) ;
2015-05-11 04:45:38 +02:00
return Modal ;
2018-07-24 02:51:14 +02:00
2019-11-08 09:11:23 +01:00
} ) ) ) ;
2018-07-24 02:51:14 +02:00
//# sourceMappingURL=modal.js.map