|
|
/*! * Bootstrap collapse.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)
*/ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) : typeof define === 'function' && define.amd ? define(['./dom/data', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Collapse = factory(global.Data, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base)); })(this, (function (Data, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
const Data__default = /*#__PURE__*/_interopDefaultLegacy(Data); const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler); const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator); const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine); 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 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('#')) { hrefAttr = `#${hrefAttr.split('#')[1]}`; }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; }
return selector; };
const getSelectorFromElement = element => { const selector = getSelector(element);
if (selector) { return document.querySelector(selector) ? selector : null; }
return null; };
const getElementFromSelector = element => { const selector = getSelector(element); return selector ? document.querySelector(selector) : null; };
const isElement = obj => { if (!obj || typeof obj !== 'object') { return false; }
if (typeof obj.jquery !== 'undefined') { obj = obj[0]; }
return typeof obj.nodeType !== 'undefined'; };
const getElement = obj => { if (isElement(obj)) { // it's a jQuery object or a node element
return obj.jquery ? obj[0] : obj; }
if (typeof obj === 'string' && obj.length > 0) { return document.querySelector(obj); }
return null; };
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)) { throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); } }); }; /** * 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 => { // eslint-disable-next-line no-unused-expressions
element.offsetHeight; };
const getjQuery = () => { const { jQuery } = window;
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { return jQuery; }
return null; };
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = callback => { if (document.readyState === 'loading') { // 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); } else { callback(); } };
const defineJQueryPlugin = plugin => { onDOMContentLoaded(() => { const $ = getjQuery(); /* istanbul ignore if */
if ($) { const name = plugin.NAME; 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; }; } }); };
/** * -------------------------------------------------------------------------- * Bootstrap (v5.1.3): collapse.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */
const NAME = 'collapse'; const DATA_KEY = 'bs.collapse'; const EVENT_KEY = `.${DATA_KEY}`; const DATA_API_KEY = '.data-api'; const Default = { toggle: true, parent: null }; const DefaultType = { toggle: 'boolean', parent: '(null|element)' }; 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}`; const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_COLLAPSE = 'collapse'; const CLASS_NAME_COLLAPSING = 'collapsing'; const CLASS_NAME_COLLAPSED = 'collapsed'; const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'; const WIDTH = 'width'; const HEIGHT = 'height'; const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]'; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */
class Collapse extends BaseComponent__default.default { constructor(element, config) { super(element); this._isTransitioning = false; this._config = this._getConfig(config); this._triggerArray = []; const toggleList = SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);
for (let i = 0, len = toggleList.length; i < len; i++) { const elem = toggleList[i]; const selector = getSelectorFromElement(elem); const filterElement = SelectorEngine__default.default.find(selector).filter(foundElem => foundElem === this._element);
if (selector !== null && filterElement.length) { this._selector = selector;
this._triggerArray.push(elem); } }
this._initializeChildren();
if (!this._config.parent) { this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); }
if (this._config.toggle) { this.toggle(); } } // Getters
static get Default() { return Default; }
static get NAME() { return NAME; } // Public
toggle() { if (this._isShown()) { this.hide(); } else { this.show(); } }
show() { if (this._isTransitioning || this._isShown()) { return; }
let actives = []; let activesData;
if (this._config.parent) { const children = SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); actives = SelectorEngine__default.default.find(SELECTOR_ACTIVES, this._config.parent).filter(elem => !children.includes(elem)); // remove children if greater depth
}
const container = SelectorEngine__default.default.findOne(this._selector);
if (actives.length) { const tempActiveData = actives.find(elem => container !== elem); activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;
if (activesData && activesData._isTransitioning) { return; } }
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW);
if (startEvent.defaultPrevented) { return; }
actives.forEach(elemActive => { if (container !== elemActive) { Collapse.getOrCreateInstance(elemActive, { toggle: false }).hide(); }
if (!activesData) { Data__default.default.set(elemActive, DATA_KEY, null); } });
const dimension = this._getDimension();
this._element.classList.remove(CLASS_NAME_COLLAPSE);
this._element.classList.add(CLASS_NAME_COLLAPSING);
this._element.style[dimension] = 0;
this._addAriaAndCollapsedClass(this._triggerArray, true);
this._isTransitioning = true;
const complete = () => { this._isTransitioning = false;
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
this._element.style[dimension] = ''; EventHandler__default.default.trigger(this._element, EVENT_SHOWN); };
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); const scrollSize = `scroll${capitalizedDimension}`;
this._queueCallback(complete, this._element, true);
this._element.style[dimension] = `${this._element[scrollSize]}px`; }
hide() { if (this._isTransitioning || !this._isShown()) { return; }
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
if (startEvent.defaultPrevented) { return; }
const dimension = this._getDimension();
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; reflow(this._element);
this._element.classList.add(CLASS_NAME_COLLAPSING);
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
const triggerArrayLength = this._triggerArray.length;
for (let i = 0; i < triggerArrayLength; i++) { const trigger = this._triggerArray[i]; const elem = getElementFromSelector(trigger);
if (elem && !this._isShown(elem)) { this._addAriaAndCollapsedClass([trigger], false); } }
this._isTransitioning = true;
const complete = () => { this._isTransitioning = false;
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE);
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN); };
this._element.style[dimension] = '';
this._queueCallback(complete, this._element, true); }
_isShown(element = this._element) { return element.classList.contains(CLASS_NAME_SHOW); } // Private
_getConfig(config) { config = { ...Default, ...Manipulator__default.default.getDataAttributes(this._element), ...config }; config.toggle = Boolean(config.toggle); // Coerce string values
config.parent = getElement(config.parent); typeCheckConfig(NAME, config, DefaultType); return config; }
_getDimension() { return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; }
_initializeChildren() { if (!this._config.parent) { return; }
const children = SelectorEngine__default.default.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE, this._config.parent).filter(elem => !children.includes(elem)).forEach(element => { const selected = getElementFromSelector(element);
if (selected) { this._addAriaAndCollapsedClass([element], this._isShown(selected)); } }); }
_addAriaAndCollapsedClass(triggerArray, isOpen) { if (!triggerArray.length) { return; }
triggerArray.forEach(elem => { if (isOpen) { elem.classList.remove(CLASS_NAME_COLLAPSED); } else { elem.classList.add(CLASS_NAME_COLLAPSED); }
elem.setAttribute('aria-expanded', isOpen); }); } // Static
static jQueryInterface(config) { return this.each(function () { const _config = {};
if (typeof config === 'string' && /show|hide/.test(config)) { _config.toggle = false; }
const data = Collapse.getOrCreateInstance(this, _config);
if (typeof config === 'string') { if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`); }
data[config](); } }); }
} /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') { event.preventDefault(); }
const selector = getSelectorFromElement(this); const selectorElements = SelectorEngine__default.default.find(selector); selectorElements.forEach(element => { Collapse.getOrCreateInstance(element, { toggle: false }).toggle(); }); }); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ * add .Collapse to jQuery only if jQuery is present */
defineJQueryPlugin(Collapse);
return Collapse;
})); //# sourceMappingURL=collapse.js.map
|