2021-03-23 17:26:54 +01:00
/ * !
2021-10-05 17:50:18 +02:00
* Bootstrap offcanvas . js v5 . 1.2 ( https : //getbootstrap.com/)
2021-03-23 17:26:54 +01:00
* Copyright 2011 - 2021 The Bootstrap Authors ( https : //github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* /
( function ( global , factory ) {
2021-06-22 20:29:16 +02:00
typeof exports === 'object' && typeof module !== 'undefined' ? module . exports = factory ( require ( './dom/selector-engine.js' ) , require ( './dom/manipulator.js' ) , require ( './dom/event-handler.js' ) , require ( './base-component.js' ) ) :
typeof define === 'function' && define . amd ? define ( [ './dom/selector-engine' , './dom/manipulator' , './dom/event-handler' , './base-component' ] , factory ) :
( global = typeof globalThis !== 'undefined' ? globalThis : global || self , global . Offcanvas = factory ( global . SelectorEngine , global . Manipulator , global . EventHandler , global . Base ) ) ;
2021-10-05 17:50:18 +02:00
} ) ( this , ( function ( SelectorEngine , Manipulator , EventHandler , BaseComponent ) { 'use strict' ;
2021-03-23 17:26:54 +01:00
2021-10-05 17:50:18 +02:00
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default : e } ;
2021-03-23 17:26:54 +01:00
2021-10-05 17:50:18 +02:00
const SelectorEngine _ _default = /*#__PURE__*/ _interopDefaultLegacy ( SelectorEngine ) ;
const Manipulator _ _default = /*#__PURE__*/ _interopDefaultLegacy ( Manipulator ) ;
const EventHandler _ _default = /*#__PURE__*/ _interopDefaultLegacy ( EventHandler ) ;
const BaseComponent _ _default = /*#__PURE__*/ _interopDefaultLegacy ( BaseComponent ) ;
2021-03-23 17:26:54 +01:00
2021-08-04 17:41:51 +02:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : util / index . js
2021-08-04 17:41:51 +02:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-03-23 17:26:54 +01:00
const MILLISECONDS _MULTIPLIER = 1000 ;
2021-05-05 21:32:12 +02:00
const TRANSITION _END = 'transitionend' ; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
2021-03-23 17:26:54 +01:00
const toType = obj => {
if ( obj === null || obj === undefined ) {
return ` ${ obj } ` ;
}
return { } . toString . call ( obj ) . match ( /\s([a-z]+)/i ) [ 1 ] . toLowerCase ( ) ;
} ;
const getSelector = element => {
let selector = element . getAttribute ( 'data-bs-target' ) ;
if ( ! selector || selector === '#' ) {
let hrefAttr = element . getAttribute ( 'href' ) ; // The only valid content that could double as a selector are IDs or classes,
// 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-03-23 17:26:54 +01:00
}
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr . trim ( ) : null ;
}
return selector ;
} ;
const getElementFromSelector = element => {
const selector = getSelector ( element ) ;
return selector ? document . querySelector ( selector ) : null ;
} ;
const getTransitionDurationFromElement = element => {
if ( ! element ) {
return 0 ;
} // Get transition-duration of the element
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
if ( ! floatTransitionDuration && ! floatTransitionDelay ) {
return 0 ;
} // If multiple durations are defined, take the first
transitionDuration = transitionDuration . split ( ',' ) [ 0 ] ;
transitionDelay = transitionDelay . split ( ',' ) [ 0 ] ;
return ( Number . parseFloat ( transitionDuration ) + Number . parseFloat ( transitionDelay ) ) * MILLISECONDS _MULTIPLIER ;
} ;
2021-05-05 21:32:12 +02:00
const triggerTransitionEnd = element => {
element . dispatchEvent ( new Event ( TRANSITION _END ) ) ;
} ;
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' ;
} ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
const getElement = obj => {
if ( isElement ( obj ) ) {
// it's a jQuery object or a node element
return obj . jquery ? obj [ 0 ] : obj ;
}
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
if ( typeof obj === 'string' && obj . length > 0 ) {
2021-08-04 17:41:51 +02:00
return document . querySelector ( obj ) ;
2021-05-05 21:32:12 +02:00
}
2021-06-22 20:29:16 +02:00
return null ;
2021-05-05 21:32:12 +02:00
} ;
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 ) ;
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 } ". ` ) ;
2021-03-23 17:26:54 +01:00
}
} ) ;
} ;
const isVisible = element => {
2021-06-22 20:29:16 +02:00
if ( ! isElement ( element ) || element . getClientRects ( ) . length === 0 ) {
2021-03-23 17:26:54 +01:00
return false ;
}
2021-06-22 20:29:16 +02:00
return getComputedStyle ( element ) . getPropertyValue ( 'visibility' ) === 'visible' ;
2021-03-23 17:26:54 +01:00
} ;
const isDisabled = element => {
if ( ! element || element . nodeType !== Node . ELEMENT _NODE ) {
return true ;
}
if ( element . classList . contains ( 'disabled' ) ) {
return true ;
}
if ( typeof element . disabled !== 'undefined' ) {
return element . disabled ;
}
return element . hasAttribute ( 'disabled' ) && element . getAttribute ( 'disabled' ) !== 'false' ;
} ;
2021-08-04 17:41:51 +02:00
/ * *
* Trick to restart an element ' s animation
*
* @ param { HTMLElement } element
* @ return void
*
* @ see https : //www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
* /
2021-03-23 17:26:54 +01:00
2021-08-04 17:41:51 +02:00
const reflow = element => {
// eslint-disable-next-line no-unused-expressions
element . offsetHeight ;
} ;
2021-05-05 21:32:12 +02:00
2021-03-23 17:26:54 +01:00
const getjQuery = ( ) => {
const {
jQuery
} = window ;
if ( jQuery && ! document . body . hasAttribute ( 'data-bs-no-jquery' ) ) {
return jQuery ;
}
return null ;
} ;
2021-06-22 20:29:16 +02:00
const DOMContentLoadedCallbacks = [ ] ;
2021-03-23 17:26:54 +01:00
const onDOMContentLoaded = callback => {
if ( document . readyState === 'loading' ) {
2021-06-22 20:29:16 +02:00
// add listener on the first call when the document is in loading state
if ( ! DOMContentLoadedCallbacks . length ) {
document . addEventListener ( 'DOMContentLoaded' , ( ) => {
DOMContentLoadedCallbacks . forEach ( callback => callback ( ) ) ;
} ) ;
}
DOMContentLoadedCallbacks . push ( callback ) ;
2021-03-23 17:26:54 +01:00
} else {
callback ( ) ;
}
} ;
2021-05-13 18:22:20 +02:00
const defineJQueryPlugin = plugin => {
2021-03-23 17:26:54 +01:00
onDOMContentLoaded ( ( ) => {
const $ = getjQuery ( ) ;
/* istanbul ignore if */
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 ] ;
$ . fn [ name ] = plugin . jQueryInterface ;
$ . fn [ name ] . Constructor = plugin ;
$ . fn [ name ] . noConflict = ( ) => {
$ . fn [ name ] = JQUERY _NO _CONFLICT ;
return plugin . jQueryInterface ;
} ;
}
} ) ;
} ;
2021-05-05 21:32:12 +02:00
const execute = callback => {
if ( typeof callback === 'function' ) {
callback ( ) ;
}
} ;
2021-06-22 20:29:16 +02:00
const executeAfterTransition = ( callback , transitionElement , waitForTransition = true ) => {
if ( ! waitForTransition ) {
execute ( callback ) ;
return ;
}
const durationPadding = 5 ;
const emulatedDuration = getTransitionDurationFromElement ( transitionElement ) + durationPadding ;
let called = false ;
const handler = ( {
target
} ) => {
if ( target !== transitionElement ) {
return ;
}
called = true ;
transitionElement . removeEventListener ( TRANSITION _END , handler ) ;
execute ( callback ) ;
} ;
transitionElement . addEventListener ( TRANSITION _END , handler ) ;
setTimeout ( ( ) => {
if ( ! called ) {
triggerTransitionEnd ( transitionElement ) ;
}
} , emulatedDuration ) ;
} ;
2021-03-23 17:26:54 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : util / scrollBar . js
2021-03-23 17:26:54 +01:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-05-05 21:32:12 +02:00
const SELECTOR _FIXED _CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' ;
2021-03-23 17:26:54 +01:00
const SELECTOR _STICKY _CONTENT = '.sticky-top' ;
2021-06-22 20:29:16 +02:00
class ScrollBarHelper {
constructor ( ) {
this . _element = document . body ;
}
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
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 ) ;
}
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
hide ( ) {
const width = this . getWidth ( ) ;
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
this . _disableOverFlow ( ) ; // give padding to element to balance the hidden scrollbar width
2021-05-05 21:32:12 +02:00
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
this . _setElementAttributes ( this . _element , 'paddingRight' , calculatedValue => calculatedValue + width ) ; // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
this . _setElementAttributes ( SELECTOR _FIXED _CONTENT , 'paddingRight' , calculatedValue => calculatedValue + width ) ;
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
this . _setElementAttributes ( SELECTOR _STICKY _CONTENT , 'marginRight' , calculatedValue => calculatedValue - width ) ;
2021-05-05 21:32:12 +02:00
}
2021-06-22 20:29:16 +02:00
_disableOverFlow ( ) {
this . _saveInitialAttribute ( this . _element , 'overflow' ) ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
this . _element . style . overflow = 'hidden' ;
}
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
_setElementAttributes ( selector , styleProp , callback ) {
const scrollbarWidth = this . getWidth ( ) ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
const manipulationCallBack = element => {
if ( element !== this . _element && window . innerWidth > element . clientWidth + scrollbarWidth ) {
return ;
}
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
this . _saveInitialAttribute ( element , styleProp ) ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
const calculatedValue = window . getComputedStyle ( element ) [ styleProp ] ;
element . style [ styleProp ] = ` ${ callback ( Number . parseFloat ( calculatedValue ) ) } px ` ;
} ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
this . _applyManipulationCallback ( selector , manipulationCallBack ) ;
}
reset ( ) {
this . _resetElementAttributes ( this . _element , 'overflow' ) ;
this . _resetElementAttributes ( this . _element , 'paddingRight' ) ;
this . _resetElementAttributes ( SELECTOR _FIXED _CONTENT , 'paddingRight' ) ;
this . _resetElementAttributes ( SELECTOR _STICKY _CONTENT , 'marginRight' ) ;
}
_saveInitialAttribute ( element , styleProp ) {
const actualValue = element . style [ styleProp ] ;
if ( actualValue ) {
2021-10-05 17:50:18 +02:00
Manipulator _ _default . default . setDataAttribute ( element , styleProp , actualValue ) ;
2021-06-22 20:29:16 +02:00
}
}
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
_resetElementAttributes ( selector , styleProp ) {
const manipulationCallBack = element => {
2021-10-05 17:50:18 +02:00
const value = Manipulator _ _default . default . getDataAttribute ( element , styleProp ) ;
2021-03-23 17:26:54 +01:00
2021-06-22 20:29:16 +02:00
if ( typeof value === 'undefined' ) {
element . style . removeProperty ( styleProp ) ;
} else {
2021-10-05 17:50:18 +02:00
Manipulator _ _default . default . removeDataAttribute ( element , styleProp ) ;
2021-06-22 20:29:16 +02:00
element . style [ styleProp ] = value ;
}
} ;
this . _applyManipulationCallback ( selector , manipulationCallBack ) ;
}
_applyManipulationCallback ( selector , callBack ) {
if ( isElement ( selector ) ) {
callBack ( selector ) ;
2021-03-23 17:26:54 +01:00
} else {
2021-10-05 17:50:18 +02:00
SelectorEngine _ _default . default . find ( selector , this . _element ) . forEach ( callBack ) ;
2021-03-23 17:26:54 +01:00
}
2021-06-22 20:29:16 +02:00
}
isOverflowing ( ) {
return this . getWidth ( ) > 0 ;
}
}
2021-03-23 17:26:54 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : util / backdrop . js
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
2021-05-05 21:32:12 +02:00
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-08-04 17:41:51 +02:00
const Default$2 = {
className : 'modal-backdrop' ,
2021-05-05 21:32:12 +02:00
isVisible : true ,
// if false, we use the backdrop helper without adding any element to the dom
isAnimated : false ,
2021-06-22 20:29:16 +02:00
rootElement : 'body' ,
2021-05-05 21:32:12 +02:00
// give the choice to place backdrop under different elements
clickCallback : null
} ;
2021-08-04 17:41:51 +02:00
const DefaultType$2 = {
className : 'string' ,
2021-05-05 21:32:12 +02:00
isVisible : 'boolean' ,
isAnimated : 'boolean' ,
2021-06-22 20:29:16 +02:00
rootElement : '(element|string)' ,
2021-05-05 21:32:12 +02:00
clickCallback : '(function|null)'
} ;
2021-08-04 17:41:51 +02:00
const NAME$2 = 'backdrop' ;
2021-05-05 21:32:12 +02:00
const CLASS _NAME _FADE = 'fade' ;
const CLASS _NAME _SHOW$1 = 'show' ;
2021-08-04 17:41:51 +02:00
const EVENT _MOUSEDOWN = ` mousedown.bs. ${ NAME$2 } ` ;
2021-05-05 21:32:12 +02:00
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' ) ;
2021-08-04 17:41:51 +02:00
backdrop . className = this . _config . className ;
2021-05-05 21:32:12 +02:00
if ( this . _config . isAnimated ) {
backdrop . classList . add ( CLASS _NAME _FADE ) ;
}
this . _element = backdrop ;
}
return this . _element ;
}
_getConfig ( config ) {
2021-08-04 17:41:51 +02:00
config = { ... Default$2 ,
2021-05-05 21:32:12 +02:00
... ( typeof config === 'object' ? config : { } )
2021-06-22 20:29:16 +02:00
} ; // use getElement() with the default "body" to get a fresh Element on each instantiation
config . rootElement = getElement ( config . rootElement ) ;
2021-08-04 17:41:51 +02:00
typeCheckConfig ( NAME$2 , config , DefaultType$2 ) ;
2021-05-05 21:32:12 +02:00
return config ;
}
_append ( ) {
if ( this . _isAppended ) {
return ;
}
2021-08-04 17:41:51 +02:00
this . _config . rootElement . append ( this . _getElement ( ) ) ;
2021-05-05 21:32:12 +02:00
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . on ( this . _getElement ( ) , EVENT _MOUSEDOWN , ( ) => {
2021-05-05 21:32:12 +02:00
execute ( this . _config . clickCallback ) ;
} ) ;
this . _isAppended = true ;
}
dispose ( ) {
if ( ! this . _isAppended ) {
return ;
}
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . off ( this . _element , EVENT _MOUSEDOWN ) ;
2021-05-05 21:32:12 +02:00
2021-06-22 20:29:16 +02:00
this . _element . remove ( ) ;
2021-05-05 21:32:12 +02:00
this . _isAppended = false ;
}
_emulateAnimation ( callback ) {
2021-06-22 20:29:16 +02:00
executeAfterTransition ( callback , this . _getElement ( ) , this . _config . isAnimated ) ;
2021-05-05 21:32:12 +02:00
}
}
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : util / focustrap . js
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
2021-08-04 17:41:51 +02:00
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const Default$1 = {
trapElement : null ,
// The element to trap focus inside of
autofocus : true
} ;
const DefaultType$1 = {
trapElement : 'element' ,
autofocus : 'boolean'
} ;
const NAME$1 = 'focustrap' ;
const DATA _KEY$1 = 'bs.focustrap' ;
const EVENT _KEY$1 = ` . ${ DATA _KEY$1 } ` ;
const EVENT _FOCUSIN = ` focusin ${ EVENT _KEY$1 } ` ;
const EVENT _KEYDOWN _TAB = ` keydown.tab ${ EVENT _KEY$1 } ` ;
const TAB _KEY = 'Tab' ;
const TAB _NAV _FORWARD = 'forward' ;
const TAB _NAV _BACKWARD = 'backward' ;
class FocusTrap {
constructor ( config ) {
this . _config = this . _getConfig ( config ) ;
this . _isActive = false ;
this . _lastTabNavDirection = null ;
}
activate ( ) {
const {
trapElement ,
autofocus
} = this . _config ;
if ( this . _isActive ) {
return ;
}
if ( autofocus ) {
trapElement . focus ( ) ;
}
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . off ( document , EVENT _KEY$1 ) ; // guard against infinite focus loop
2021-08-04 17:41:51 +02:00
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . on ( document , EVENT _FOCUSIN , event => this . _handleFocusin ( event ) ) ;
EventHandler _ _default . default . on ( document , EVENT _KEYDOWN _TAB , event => this . _handleKeydown ( event ) ) ;
2021-08-04 17:41:51 +02:00
this . _isActive = true ;
}
deactivate ( ) {
if ( ! this . _isActive ) {
return ;
}
this . _isActive = false ;
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . off ( document , EVENT _KEY$1 ) ;
2021-08-04 17:41:51 +02:00
} // Private
_handleFocusin ( event ) {
const {
target
} = event ;
const {
trapElement
} = this . _config ;
if ( target === document || target === trapElement || trapElement . contains ( target ) ) {
return ;
}
2021-10-05 17:50:18 +02:00
const elements = SelectorEngine _ _default . default . focusableChildren ( trapElement ) ;
2021-08-04 17:41:51 +02:00
if ( elements . length === 0 ) {
trapElement . focus ( ) ;
} else if ( this . _lastTabNavDirection === TAB _NAV _BACKWARD ) {
elements [ elements . length - 1 ] . focus ( ) ;
} else {
elements [ 0 ] . focus ( ) ;
}
}
_handleKeydown ( event ) {
if ( event . key !== TAB _KEY ) {
return ;
}
this . _lastTabNavDirection = event . shiftKey ? TAB _NAV _BACKWARD : TAB _NAV _FORWARD ;
}
_getConfig ( config ) {
config = { ... Default$1 ,
... ( typeof config === 'object' ? config : { } )
} ;
typeCheckConfig ( NAME$1 , config , DefaultType$1 ) ;
return config ;
}
}
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : util / component - functions . js
2021-08-04 17:41:51 +02:00
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const enableDismissTrigger = ( component , method = 'hide' ) => {
const clickEvent = ` click.dismiss ${ component . EVENT _KEY } ` ;
const name = component . NAME ;
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . on ( document , clickEvent , ` [data-bs-dismiss=" ${ name } "] ` , function ( event ) {
2021-08-04 17:41:51 +02:00
if ( [ 'A' , 'AREA' ] . includes ( this . tagName ) ) {
event . preventDefault ( ) ;
}
if ( isDisabled ( this ) ) {
return ;
}
const target = getElementFromSelector ( this ) || this . closest ( ` . ${ name } ` ) ;
const instance = component . getOrCreateInstance ( target ) ; // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
instance [ method ] ( ) ;
} ) ;
} ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2021-10-05 17:50:18 +02:00
* Bootstrap ( v5 . 1.2 ) : offcanvas . js
* Licensed under MIT ( https : //github.com/twbs/bootstrap/blob/main/LICENSE)
2021-03-23 17:26:54 +01:00
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Constants
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
const NAME = 'offcanvas' ;
const DATA _KEY = 'bs.offcanvas' ;
const EVENT _KEY = ` . ${ DATA _KEY } ` ;
const DATA _API _KEY = '.data-api' ;
const EVENT _LOAD _DATA _API = ` load ${ EVENT _KEY } ${ DATA _API _KEY } ` ;
const ESCAPE _KEY = 'Escape' ;
const Default = {
backdrop : true ,
keyboard : true ,
scroll : false
} ;
const DefaultType = {
backdrop : 'boolean' ,
keyboard : 'boolean' ,
scroll : 'boolean'
} ;
const CLASS _NAME _SHOW = 'show' ;
2021-08-04 17:41:51 +02:00
const CLASS _NAME _BACKDROP = 'offcanvas-backdrop' ;
2021-03-23 17:26:54 +01:00
const OPEN _SELECTOR = '.offcanvas.show' ;
const EVENT _SHOW = ` show ${ EVENT _KEY } ` ;
const EVENT _SHOWN = ` shown ${ EVENT _KEY } ` ;
const EVENT _HIDE = ` hide ${ EVENT _KEY } ` ;
const EVENT _HIDDEN = ` hidden ${ EVENT _KEY } ` ;
const EVENT _CLICK _DATA _API = ` click ${ EVENT _KEY } ${ DATA _API _KEY } ` ;
2021-05-05 21:32:12 +02:00
const EVENT _KEYDOWN _DISMISS = ` keydown.dismiss ${ EVENT _KEY } ` ;
2021-03-23 17:26:54 +01:00
const SELECTOR _DATA _TOGGLE = '[data-bs-toggle="offcanvas"]' ;
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Class Definition
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-10-05 17:50:18 +02:00
class Offcanvas extends BaseComponent _ _default . default {
2021-03-23 17:26:54 +01:00
constructor ( element , config ) {
super ( element ) ;
this . _config = this . _getConfig ( config ) ;
this . _isShown = false ;
2021-05-05 21:32:12 +02:00
this . _backdrop = this . _initializeBackDrop ( ) ;
2021-08-04 17:41:51 +02:00
this . _focustrap = this . _initializeFocusTrap ( ) ;
2021-03-23 17:26:54 +01:00
this . _addEventListeners ( ) ;
} // Getters
2021-05-13 18:22:20 +02:00
static get NAME ( ) {
return NAME ;
2021-03-23 17:26:54 +01:00
}
2021-05-13 18:22:20 +02:00
static get Default ( ) {
return Default ;
2021-03-23 17:26:54 +01:00
} // Public
toggle ( relatedTarget ) {
return this . _isShown ? this . hide ( ) : this . show ( relatedTarget ) ;
}
show ( relatedTarget ) {
if ( this . _isShown ) {
return ;
}
2021-10-05 17:50:18 +02:00
const showEvent = EventHandler _ _default . default . trigger ( this . _element , EVENT _SHOW , {
2021-03-23 17:26:54 +01:00
relatedTarget
} ) ;
if ( showEvent . defaultPrevented ) {
return ;
}
this . _isShown = true ;
this . _element . style . visibility = 'visible' ;
2021-05-05 21:32:12 +02:00
this . _backdrop . show ( ) ;
2021-03-23 17:26:54 +01:00
if ( ! this . _config . scroll ) {
2021-06-22 20:29:16 +02:00
new ScrollBarHelper ( ) . hide ( ) ;
2021-05-05 21:32:12 +02:00
}
2021-03-23 17:26:54 +01:00
this . _element . removeAttribute ( 'aria-hidden' ) ;
this . _element . setAttribute ( 'aria-modal' , true ) ;
this . _element . setAttribute ( 'role' , 'dialog' ) ;
this . _element . classList . add ( CLASS _NAME _SHOW ) ;
const completeCallBack = ( ) => {
2021-08-04 17:41:51 +02:00
if ( ! this . _config . scroll ) {
this . _focustrap . activate ( ) ;
}
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . trigger ( this . _element , EVENT _SHOWN , {
2021-03-23 17:26:54 +01:00
relatedTarget
} ) ;
} ;
2021-05-13 18:22:20 +02:00
this . _queueCallback ( completeCallBack , this . _element , true ) ;
2021-03-23 17:26:54 +01:00
}
hide ( ) {
if ( ! this . _isShown ) {
return ;
}
2021-10-05 17:50:18 +02:00
const hideEvent = EventHandler _ _default . default . trigger ( this . _element , EVENT _HIDE ) ;
2021-03-23 17:26:54 +01:00
if ( hideEvent . defaultPrevented ) {
return ;
}
2021-08-04 17:41:51 +02:00
this . _focustrap . deactivate ( ) ;
2021-03-23 17:26:54 +01:00
this . _element . blur ( ) ;
this . _isShown = false ;
this . _element . classList . remove ( CLASS _NAME _SHOW ) ;
2021-05-05 21:32:12 +02:00
this . _backdrop . hide ( ) ;
2021-03-23 17:26:54 +01:00
const completeCallback = ( ) => {
this . _element . setAttribute ( 'aria-hidden' , true ) ;
this . _element . removeAttribute ( 'aria-modal' ) ;
this . _element . removeAttribute ( 'role' ) ;
this . _element . style . visibility = 'hidden' ;
if ( ! this . _config . scroll ) {
2021-06-22 20:29:16 +02:00
new ScrollBarHelper ( ) . reset ( ) ;
2021-03-23 17:26:54 +01:00
}
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . trigger ( this . _element , EVENT _HIDDEN ) ;
2021-03-23 17:26:54 +01:00
} ;
2021-05-13 18:22:20 +02:00
this . _queueCallback ( completeCallback , this . _element , true ) ;
2021-05-05 21:32:12 +02:00
}
dispose ( ) {
this . _backdrop . dispose ( ) ;
2021-08-04 17:41:51 +02:00
this . _focustrap . deactivate ( ) ;
2021-05-05 21:32:12 +02:00
super . dispose ( ) ;
2021-03-23 17:26:54 +01:00
} // Private
_getConfig ( config ) {
config = { ... Default ,
2021-10-05 17:50:18 +02:00
... Manipulator _ _default . default . getDataAttributes ( this . _element ) ,
2021-03-23 17:26:54 +01:00
... ( typeof config === 'object' ? config : { } )
} ;
typeCheckConfig ( NAME , config , DefaultType ) ;
return config ;
}
2021-05-05 21:32:12 +02:00
_initializeBackDrop ( ) {
return new Backdrop ( {
2021-08-04 17:41:51 +02:00
className : CLASS _NAME _BACKDROP ,
2021-05-05 21:32:12 +02:00
isVisible : this . _config . backdrop ,
isAnimated : true ,
rootElement : this . _element . parentNode ,
clickCallback : ( ) => this . hide ( )
} ) ;
}
2021-08-04 17:41:51 +02:00
_initializeFocusTrap ( ) {
return new FocusTrap ( {
trapElement : this . _element
2021-03-23 17:26:54 +01:00
} ) ;
}
_addEventListeners ( ) {
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . on ( this . _element , EVENT _KEYDOWN _DISMISS , event => {
2021-03-23 17:26:54 +01:00
if ( this . _config . keyboard && event . key === ESCAPE _KEY ) {
this . hide ( ) ;
}
} ) ;
} // Static
static jQueryInterface ( config ) {
return this . each ( function ( ) {
2021-06-22 20:29:16 +02:00
const data = Offcanvas . getOrCreateInstance ( this , config ) ;
2021-03-23 17:26:54 +01:00
if ( typeof config !== 'string' ) {
return ;
}
if ( data [ config ] === undefined || config . startsWith ( '_' ) || config === 'constructor' ) {
throw new TypeError ( ` No method named " ${ config } " ` ) ;
}
data [ config ] ( this ) ;
} ) ;
}
}
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* Data Api implementation
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-10-05 17:50:18 +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 ) ;
if ( [ 'A' , 'AREA' ] . includes ( this . tagName ) ) {
event . preventDefault ( ) ;
}
if ( isDisabled ( this ) ) {
return ;
}
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . one ( target , EVENT _HIDDEN , ( ) => {
2021-03-23 17:26:54 +01:00
// focus on trigger when it is closed
if ( isVisible ( this ) ) {
this . focus ( ) ;
}
} ) ; // avoid conflict when clicking a toggler of an offcanvas, while another is open
2021-10-05 17:50:18 +02:00
const allReadyOpen = SelectorEngine _ _default . default . findOne ( OPEN _SELECTOR ) ;
2021-03-23 17:26:54 +01:00
if ( allReadyOpen && allReadyOpen !== target ) {
2021-05-05 21:32:12 +02:00
Offcanvas . getInstance ( allReadyOpen ) . hide ( ) ;
2021-03-23 17:26:54 +01:00
}
2021-06-22 20:29:16 +02:00
const data = Offcanvas . getOrCreateInstance ( target ) ;
2021-03-23 17:26:54 +01:00
data . toggle ( this ) ;
} ) ;
2021-10-05 17:50:18 +02:00
EventHandler _ _default . default . on ( window , EVENT _LOAD _DATA _API , ( ) => SelectorEngine _ _default . default . find ( OPEN _SELECTOR ) . forEach ( el => Offcanvas . getOrCreateInstance ( el ) . show ( ) ) ) ;
2021-08-04 17:41:51 +02:00
enableDismissTrigger ( Offcanvas ) ;
2021-03-23 17:26:54 +01:00
/ * *
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* jQuery
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* /
2021-05-13 18:22:20 +02:00
defineJQueryPlugin ( Offcanvas ) ;
2021-03-23 17:26:54 +01:00
return Offcanvas ;
2021-10-05 17:50:18 +02:00
} ) ) ;
2021-03-23 17:26:54 +01:00
//# sourceMappingURL=offcanvas.js.map