diff options
Diffstat (limited to 'vendor/twbs/bootstrap/js/dist/offcanvas.js')
-rw-r--r-- | vendor/twbs/bootstrap/js/dist/offcanvas.js | 260 |
1 files changed, 203 insertions, 57 deletions
diff --git a/vendor/twbs/bootstrap/js/dist/offcanvas.js b/vendor/twbs/bootstrap/js/dist/offcanvas.js index 529a294ff..9b9ab6a3c 100644 --- a/vendor/twbs/bootstrap/js/dist/offcanvas.js +++ b/vendor/twbs/bootstrap/js/dist/offcanvas.js @@ -1,5 +1,5 @@ /*! - * Bootstrap offcanvas.js v5.0.2 (https://getbootstrap.com/) + * Bootstrap offcanvas.js v5.1.3 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) */ @@ -7,15 +7,21 @@ 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)); -}(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict'; +})(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict'; - function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e }; - var SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine); - var Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator); - var EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler); - var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent); + const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine); + const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator); + const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler); + const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent); + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.1.3): util/index.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ const MILLISECONDS_MULTIPLIER = 1000; const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp) @@ -102,7 +108,7 @@ } if (typeof obj === 'string' && obj.length > 0) { - return SelectorEngine__default['default'].findOne(obj); + return document.querySelector(obj); } return null; @@ -143,8 +149,20 @@ return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; }; + /** + * 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 + */ + - const reflow = element => element.offsetHeight; + const reflow = element => { + // eslint-disable-next-line no-unused-expressions + element.offsetHeight; + }; const getjQuery = () => { const { @@ -232,7 +250,7 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): util/scrollBar.js + * Bootstrap (v5.1.3): util/scrollBar.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ @@ -301,18 +319,18 @@ const actualValue = element.style[styleProp]; if (actualValue) { - Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue); + Manipulator__default.default.setDataAttribute(element, styleProp, actualValue); } } _resetElementAttributes(selector, styleProp) { const manipulationCallBack = element => { - const value = Manipulator__default['default'].getDataAttribute(element, styleProp); + const value = Manipulator__default.default.getDataAttribute(element, styleProp); if (typeof value === 'undefined') { element.style.removeProperty(styleProp); } else { - Manipulator__default['default'].removeDataAttribute(element, styleProp); + Manipulator__default.default.removeDataAttribute(element, styleProp); element.style[styleProp] = value; } }; @@ -324,7 +342,7 @@ if (isElement(selector)) { callBack(selector); } else { - SelectorEngine__default['default'].find(selector, this._element).forEach(callBack); + SelectorEngine__default.default.find(selector, this._element).forEach(callBack); } } @@ -336,11 +354,12 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): util/backdrop.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap (v5.1.3): util/backdrop.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ - const Default$1 = { + const Default$2 = { + className: 'modal-backdrop', isVisible: true, // if false, we use the backdrop helper without adding any element to the dom isAnimated: false, @@ -348,17 +367,17 @@ // give the choice to place backdrop under different elements clickCallback: null }; - const DefaultType$1 = { + const DefaultType$2 = { + className: 'string', isVisible: 'boolean', isAnimated: 'boolean', rootElement: '(element|string)', clickCallback: '(function|null)' }; - const NAME$1 = 'backdrop'; - const CLASS_NAME_BACKDROP = 'modal-backdrop'; + const NAME$2 = 'backdrop'; const CLASS_NAME_FADE = 'fade'; const CLASS_NAME_SHOW$1 = 'show'; - const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$1}`; + const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`; class Backdrop { constructor(config) { @@ -404,7 +423,7 @@ _getElement() { if (!this._element) { const backdrop = document.createElement('div'); - backdrop.className = CLASS_NAME_BACKDROP; + backdrop.className = this._config.className; if (this._config.isAnimated) { backdrop.classList.add(CLASS_NAME_FADE); @@ -417,12 +436,12 @@ } _getConfig(config) { - config = { ...Default$1, + config = { ...Default$2, ...(typeof config === 'object' ? config : {}) }; // use getElement() with the default "body" to get a fresh Element on each instantiation config.rootElement = getElement(config.rootElement); - typeCheckConfig(NAME$1, config, DefaultType$1); + typeCheckConfig(NAME$2, config, DefaultType$2); return config; } @@ -431,9 +450,9 @@ return; } - this._config.rootElement.appendChild(this._getElement()); + this._config.rootElement.append(this._getElement()); - EventHandler__default['default'].on(this._getElement(), EVENT_MOUSEDOWN, () => { + EventHandler__default.default.on(this._getElement(), EVENT_MOUSEDOWN, () => { execute(this._config.clickCallback); }); this._isAppended = true; @@ -444,7 +463,7 @@ return; } - EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN); + EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN); this._element.remove(); @@ -459,8 +478,137 @@ /** * -------------------------------------------------------------------------- - * Bootstrap (v5.0.2): offcanvas.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Bootstrap (v5.1.3): util/focustrap.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + 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(); + } + + EventHandler__default.default.off(document, EVENT_KEY$1); // guard against infinite focus loop + + EventHandler__default.default.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event)); + EventHandler__default.default.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); + this._isActive = true; + } + + deactivate() { + if (!this._isActive) { + return; + } + + this._isActive = false; + EventHandler__default.default.off(document, EVENT_KEY$1); + } // Private + + + _handleFocusin(event) { + const { + target + } = event; + const { + trapElement + } = this._config; + + if (target === document || target === trapElement || trapElement.contains(target)) { + return; + } + + const elements = SelectorEngine__default.default.focusableChildren(trapElement); + + 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; + } + + } + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.1.3): util/component-functions.js + * 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; + EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { + 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](); + }); + }; + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.1.3): offcanvas.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ /** @@ -486,16 +634,14 @@ scroll: 'boolean' }; const CLASS_NAME_SHOW = 'show'; + const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; 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_FOCUSIN = `focusin${EVENT_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; - const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`; const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`; - const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="offcanvas"]'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]'; /** * ------------------------------------------------------------------------ @@ -503,12 +649,13 @@ * ------------------------------------------------------------------------ */ - class Offcanvas extends BaseComponent__default['default'] { + class Offcanvas extends BaseComponent__default.default { constructor(element, config) { super(element); this._config = this._getConfig(config); this._isShown = false; this._backdrop = this._initializeBackDrop(); + this._focustrap = this._initializeFocusTrap(); this._addEventListeners(); } // Getters @@ -532,7 +679,7 @@ return; } - const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, { + const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, { relatedTarget }); @@ -547,8 +694,6 @@ if (!this._config.scroll) { new ScrollBarHelper().hide(); - - this._enforceFocusOnElement(this._element); } this._element.removeAttribute('aria-hidden'); @@ -560,7 +705,11 @@ this._element.classList.add(CLASS_NAME_SHOW); const completeCallBack = () => { - EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, { + if (!this._config.scroll) { + this._focustrap.activate(); + } + + EventHandler__default.default.trigger(this._element, EVENT_SHOWN, { relatedTarget }); }; @@ -573,13 +722,13 @@ return; } - const hideEvent = EventHandler__default['default'].trigger(this._element, EVENT_HIDE); + const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE); if (hideEvent.defaultPrevented) { return; } - EventHandler__default['default'].off(document, EVENT_FOCUSIN); + this._focustrap.deactivate(); this._element.blur(); @@ -602,7 +751,7 @@ new ScrollBarHelper().reset(); } - EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN); + EventHandler__default.default.trigger(this._element, EVENT_HIDDEN); }; this._queueCallback(completeCallback, this._element, true); @@ -611,14 +760,15 @@ dispose() { this._backdrop.dispose(); + this._focustrap.deactivate(); + super.dispose(); - EventHandler__default['default'].off(document, EVENT_FOCUSIN); } // Private _getConfig(config) { config = { ...Default, - ...Manipulator__default['default'].getDataAttributes(this._element), + ...Manipulator__default.default.getDataAttributes(this._element), ...(typeof config === 'object' ? config : {}) }; typeCheckConfig(NAME, config, DefaultType); @@ -627,6 +777,7 @@ _initializeBackDrop() { return new Backdrop({ + className: CLASS_NAME_BACKDROP, isVisible: this._config.backdrop, isAnimated: true, rootElement: this._element.parentNode, @@ -634,20 +785,14 @@ }); } - _enforceFocusOnElement(element) { - EventHandler__default['default'].off(document, EVENT_FOCUSIN); // guard against infinite focus loop - - EventHandler__default['default'].on(document, EVENT_FOCUSIN, event => { - if (document !== event.target && element !== event.target && !element.contains(event.target)) { - element.focus(); - } + _initializeFocusTrap() { + return new FocusTrap({ + trapElement: this._element }); - element.focus(); } _addEventListeners() { - EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide()); - EventHandler__default['default'].on(this._element, EVENT_KEYDOWN_DISMISS, event => { + EventHandler__default.default.on(this._element, EVENT_KEYDOWN_DISMISS, event => { if (this._config.keyboard && event.key === ESCAPE_KEY) { this.hide(); } @@ -679,7 +824,7 @@ */ - EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { + EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { const target = getElementFromSelector(this); if (['A', 'AREA'].includes(this.tagName)) { @@ -690,14 +835,14 @@ return; } - EventHandler__default['default'].one(target, EVENT_HIDDEN, () => { + EventHandler__default.default.one(target, EVENT_HIDDEN, () => { // 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 - const allReadyOpen = SelectorEngine__default['default'].findOne(OPEN_SELECTOR); + const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR); if (allReadyOpen && allReadyOpen !== target) { Offcanvas.getInstance(allReadyOpen).hide(); @@ -706,7 +851,8 @@ const data = Offcanvas.getOrCreateInstance(target); data.toggle(this); }); - EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default['default'].find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show())); + EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default.default.find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show())); + enableDismissTrigger(Offcanvas); /** * ------------------------------------------------------------------------ * jQuery @@ -717,5 +863,5 @@ return Offcanvas; -}))); +})); //# sourceMappingURL=offcanvas.js.map |