release 3.10.0

This commit is contained in:
dwaju 2021-11-15 09:28:22 +01:00
parent 862c6e1b0e
commit 0fa19988ce
181 changed files with 5284 additions and 3520 deletions

View File

@ -1,5 +1,5 @@
MDB5
Version: FREE 3.9.0
Version: FREE 3.10.0
Documentation:
https://mdbootstrap.com/docs/standard/

10
css/mdb.dark.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

12
css/mdb.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

6
css/mdb.rtl.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -19,174 +19,28 @@
</head>
<body>
<!-- Start your project here-->
<!-- Container for demo purpose -->
<div class="container my-5 py-5">
<!--Counter-->
<section class="text-center">
<!-- Time Counter -->
<h1 class="mb-0 text-black">Black November <span class="text-danger fw-bold">Waiting List</span></h1>
<hr class="my-5">
<p class="text-black lead">All offers will be <span class="text-danger fw-bold">limited</span>.
Don't lose your chance, be the <span class="text-danger fw-bold">first</span> to get notified.</p>
</section>
<!--Counter-->
<!-- Section: Waiting List -->
<section class="my-5">
<style>
.fw-900 {
font-weight: 900;
}
</style>
<div class="bg-dark text-white text-center text-xl-start rounded-6">
<div class="container px-4" style="padding-top: 5rem; padding-bottom: 5rem;">
<div class="row mx-xl-1 d-flex justify-content-center justify-xl-content-start align-items-center">
<div class="col-md-10 col-lg-7 col-xl-7">
<h2 class="fs-1 fw-900">Join the waiting list <span class="text-danger fw-bold">NOW</span>
</h2>
<p class="lead fw-normal mb-4 pb-md-1 pb-xl-0 mb-xl-0">
You will only receive emails related to the Black November promotions and after the promotion is over,
you will be unsubscribed. We won't spam you.
</p>
</div>
<div class="col-md-10 col-lg-7 col-xl-5">
<div class="d-md-flex mb-3 mb-md-2 ms-xl-4">
<div class="flex-fill me-md-1 mb-3 mb-md-0">
<form action="https://app.convertkit.com/forms/2663020/subscriptions" class="seva-form formkit-form"
method="post" data-sv-form="2663020" data-uid="30443eba65" data-format="inline" data-version="5"
data-options="{&quot;settings&quot;:{&quot;after_subscribe&quot;:{&quot;action&quot;:&quot;message&quot;,&quot;success_message&quot;:&quot;Success! Now check your email to confirm your subscription.&quot;,&quot;redirect_url&quot;:&quot;https://mdbootstrap.com/confirm/&quot;},&quot;analytics&quot;:{&quot;google&quot;:null,&quot;facebook&quot;:null,&quot;segment&quot;:null,&quot;pinterest&quot;:null,&quot;sparkloop&quot;:null,&quot;googletagmanager&quot;:null},&quot;modal&quot;:{&quot;trigger&quot;:&quot;timer&quot;,&quot;scroll_percentage&quot;:null,&quot;timer&quot;:5,&quot;devices&quot;:&quot;all&quot;,&quot;show_once_every&quot;:15},&quot;powered_by&quot;:{&quot;show&quot;:false,&quot;url&quot;:&quot;https://convertkit.com?utm_campaign=poweredby&amp;utm_content=form&amp;utm_medium=referral&amp;utm_source=dynamic&quot;},&quot;recaptcha&quot;:{&quot;enabled&quot;:true},&quot;return_visitor&quot;:{&quot;action&quot;:&quot;show&quot;,&quot;custom_content&quot;:&quot;&quot;},&quot;slide_in&quot;:{&quot;display_in&quot;:&quot;bottom_right&quot;,&quot;trigger&quot;:&quot;timer&quot;,&quot;scroll_percentage&quot;:null,&quot;timer&quot;:5,&quot;devices&quot;:&quot;all&quot;,&quot;show_once_every&quot;:15},&quot;sticky_bar&quot;:{&quot;display_in&quot;:&quot;top&quot;,&quot;trigger&quot;:&quot;timer&quot;,&quot;scroll_percentage&quot;:null,&quot;timer&quot;:5,&quot;devices&quot;:&quot;all&quot;,&quot;show_once_every&quot;:15}},&quot;version&quot;:&quot;5&quot;}">
<!--Errors-->
<ul class="text-danger fw-bold" data-element="errors" data-group="alert"></ul>
<!--Fields-->
<div data-element="fields" data-stacked="false"
class="d-flex d-inline-block justify-content-center">
<!--Email address-->
<div class="form-outline form-white w-100">
<input type="text" id="form1" name="email_address" required="" type="email"
class="form-control form-control-lg" />
<label class="form-label" for="form1">Your email address</label>
</div>
<!--Button-->
<button class="btn btn-danger ms-2" data-element="submit">
JOIN
</button>
</div>
</form>
<div class="container">
<div class="d-flex justify-content-center align-items-center" style="height: 100vh;">
<div class="text-center">
<img
class="mb-4"
src="https://mdbootstrap.com/img/logo/mdb-transparent-250px.png"
style="width: 250px; height: 90px;"
/>
<h5 class="mb-3">Thank you for using our product. We're glad you're with us.</h5>
<p class="mb-3">MDB Team</p>
<a
class="btn btn-primary btn-lg"
href="https://mdbootstrap.com/docs/standard/getting-started/"
target="_blank"
role="button"
>Start MDB tutorial</a
>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="text-muted text-center">
<small>By subscribing you agree to receive Black November notifications from the data
administrator StartupFlow s.c. Kijowska 7, Warsaw.
<a href="https://mdbootstrap.com/general/privacy-policy/" class="text-decoration-underline text-reset">Privacy
Policy</a>.
</small>
</p>
</section>
<!-- Section: Waiting List -->
<!--Products-->
<section class="my-5 pt-5">
<p class="lead text-center">Explore products that will be discounted:</p>
<!--Row-->
<div class="row">
<!--Standard-->
<div class="col-md-3">
<div class="card shadow-2-strong">
<div class="bg-image hover-overlay ripple" data-mdb-ripple-color="light">
<img src="https://v1.mdbootstrap.com/wp-content/uploads/2021/10/bootstrap-standard.webp"
class="img-fluid" />
<a href="https://mdbootstrap.com/docs/standard/pro/" target="_blank">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.15)"></div>
</a>
</div>
<div class="card-body">
<h5 class="card-title">MDB Standard PRO</h5>
<p class="card-text">
Components, templates, plugins, premium support and much more for the <strong>latest Bootstrap v5 as
well as v4</strong>.
</p>
<div class="text-end">
<a href="https://mdbootstrap.com/docs/standard/pro/" type="button"
class="btn btn-sm btn-link text-muted" target="_blank">View product <i
class="fas fa-external-link-alt"></i></a>
</div>
</div>
</div>
</div>
<!--Angular-->
<div class="col-md-3">
<div class="card shadow-2-strong">
<div class="bg-image hover-overlay ripple" data-mdb-ripple-color="light">
<img src="https://v1.mdbootstrap.com/wp-content/uploads/2021/10/angular.webp" class="img-fluid" />
<a href="https://mdbootstrap.com/docs/b5/angular/pro/" target="_blank">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.15)"></div>
</a>
</div>
<div class="card-body">
<h5 class="card-title">MDB Angular PRO</h5>
<p class="card-text">
Components, templates, plugins, premium support and much more for the <strong>latest Bootstrap v5 as
well as v4</strong>.
</p>
<div class="text-end">
<a href="https://mdbootstrap.com/docs/b5/angular/pro/" type="button" class="btn btn-sm btn-link text-muted"
target="_blank">View product <i class="fas fa-external-link-alt"></i></a>
</div>
</div>
</div>
</div>
<!--React-->
<div class="col-md-3">
<div class="card shadow-2-strong">
<div class="bg-image hover-overlay ripple" data-mdb-ripple-color="light">
<img src="https://v1.mdbootstrap.com/wp-content/uploads/2021/10/react.webp" class="img-fluid" />
<a href="https://mdbootstrap.com/docs/b5/react/pro/" target="_blank">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.15)"></div>
</a>
</div>
<div class="card-body">
<h5 class="card-title">MDB React PRO</h5>
<p class="card-text">
Components, templates, plugins, premium support and much more for the <strong>latest Bootstrap v5 as
well as v4</strong>.
</p>
<div class="text-end">
<a href="https://mdbootstrap.com/docs/b5/react/pro/" type="button" class="btn btn-sm btn-link text-muted"
target="_blank">View product <i class="fas fa-external-link-alt"></i></a>
</div>
</div>
</div>
</div>
<!--Vue-->
<div class="col-md-3">
<div class="card shadow-2-strong">
<div class="bg-image hover-overlay ripple" data-mdb-ripple-color="light">
<img src="https://v1.mdbootstrap.com/wp-content/uploads/2021/10/vue.webp" class="img-fluid" />
<a href="https://mdbootstrap.com/docs/b5/vue/pro/" target="_blank">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.15)"></div>
</a>
</div>
<div class="card-body">
<h5 class="card-title">MDB Vue PRO</h5>
<p class="card-text">
Components, templates, plugins, premium support and much more for the <strong>latest Bootstrap v5 as
well as v4</strong>.
</p>
<div class="text-end">
<a href="https://mdbootstrap.com/docs/b5/vue/pro/" type="button" class="btn btn-sm btn-link text-muted"
target="_blank">View product <i class="fas fa-external-link-alt"></i></a>
</div>
</div>
</div>
</div>
</div>
</section>
<!--Products-->
</div>
<!-- Container for demo purpose -->
<!-- End your project here-->
<!-- MDB -->
<script type="text/javascript" src="js/mdb.min.js"></script>
<!-- Custom scripts -->

4
js/mdb.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "mdb-ui-kit",
"version": "3.9.0",
"version": "3.10.0",
"main": "js/mdb.min.js",
"homepage": "https://mdbootstrap.com/docs/standard/",
"repository": "https://github.com/mdbootstrap/mdb-ui-kit.git",

View File

@ -1,40 +1,30 @@
/*!
* Bootstrap alert.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap alert.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/selector-engine.js'),
require('./dom/data.js'),
require('./dom/event-handler.js'),
require('./base-component.js')
))
? (module.exports = factory(require('./dom/event-handler.js'), require('./base-component.js')))
: typeof define === 'function' && define.amd
? define([
'./dom/selector-engine',
'./dom/data',
'./dom/event-handler',
'./base-component',
], factory)
? define(['./dom/event-handler', './base-component'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Alert = factory(
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Base
)));
})(this, function (SelectorEngine, Data, EventHandler, BaseComponent) {
(global.Alert = factory(global.EventHandler, global.Base)));
})(this, function (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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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 getSelector = (element) => {
let selector = element.getAttribute('data-bs-target');
@ -64,6 +54,22 @@
return selector ? document.querySelector(selector) : null;
};
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';
};
const getjQuery = () => {
const { jQuery } = window;
@ -74,9 +80,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -103,7 +118,38 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): alert.js
* 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): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -116,12 +162,8 @@
const NAME = 'alert';
const DATA_KEY = 'bs.alert';
const EVENT_KEY = `.${DATA_KEY}`;
const DATA_API_KEY = '.data-api';
const SELECTOR_DISMISS = '[data-bs-dismiss="alert"]';
const EVENT_CLOSE = `close${EVENT_KEY}`;
const EVENT_CLOSED = `closed${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_ALERT = 'alert';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
/**
@ -130,70 +172,48 @@
* ------------------------------------------------------------------------
*/
class Alert extends BaseComponent__default['default'] {
class Alert extends BaseComponent__default.default {
// Getters
static get NAME() {
return NAME;
} // Public
close(element) {
const rootElement = element ? this._getRootElement(element) : this._element;
close() {
const closeEvent = EventHandler__default.default.trigger(this._element, EVENT_CLOSE);
const customEvent = this._triggerCloseEvent(rootElement);
if (customEvent === null || customEvent.defaultPrevented) {
if (closeEvent.defaultPrevented) {
return;
}
this._removeElement(rootElement);
this._element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
} // Private
_getRootElement(element) {
return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`);
}
_destroyElement() {
this._element.remove();
_triggerCloseEvent(element) {
return EventHandler__default['default'].trigger(element, EVENT_CLOSE);
}
_removeElement(element) {
element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(element), element, isAnimated);
}
_destroyElement(element) {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
EventHandler__default['default'].trigger(element, EVENT_CLOSED);
EventHandler__default.default.trigger(this._element, EVENT_CLOSED);
this.dispose();
} // Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY);
const data = Alert.getOrCreateInstance(this);
if (!data) {
data = new Alert(this);
if (typeof config !== 'string') {
return;
}
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
throw new TypeError(`No method named "${config}"`);
}
if (config === 'close') {
data[config](this);
}
});
}
static handleDismiss(alertInstance) {
return function (event) {
if (event) {
event.preventDefault();
}
alertInstance.close(this);
};
}
}
/**
* ------------------------------------------------------------------------
@ -201,12 +221,7 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DISMISS,
Alert.handleDismiss(new Alert())
);
enableDismissTrigger(Alert, 'close');
/**
* ------------------------------------------------------------------------
* jQuery

File diff suppressed because one or more lines are too long

View File

@ -1,30 +1,30 @@
/*!
* Bootstrap base-component.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap base-component.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/selector-engine.js'),
require('./dom/event-handler.js')
))
? (module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js')))
: typeof define === 'function' && define.amd
? define(['./dom/data', './dom/selector-engine', './dom/event-handler'], factory)
? define(['./dom/data', './dom/event-handler'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Base = factory(global.Data, global.SelectorEngine, global.EventHandler)));
})(this, function (Data, SelectorEngine, EventHandler) {
(global.Base = factory(global.Data, global.EventHandler)));
})(this, function (Data, EventHandler) {
'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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
const Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
const EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
/**
* --------------------------------------------------------------------------
* 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)
@ -72,39 +72,49 @@
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine__default['default'].findOne(obj);
return document.querySelector(obj);
}
return null;
};
const emulateTransitionEnd = (element, duration) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true;
element.removeEventListener(TRANSITION_END, listener);
}
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
triggerTransitionEnd(element);
}
}, emulatedDuration);
};
const execute = (callback) => {
if (typeof callback === 'function') {
callback();
}
};
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);
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): base-component.js
* Bootstrap (v5.1.3): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -114,7 +124,7 @@
* ------------------------------------------------------------------------
*/
const VERSION = '5.0.1';
const VERSION = '5.1.3';
class BaseComponent {
constructor(element) {
@ -125,31 +135,30 @@
}
this._element = element;
Data__default['default'].set(this._element, this.constructor.DATA_KEY, this);
Data__default.default.set(this._element, this.constructor.DATA_KEY, this);
}
dispose() {
Data__default['default'].remove(this._element, this.constructor.DATA_KEY);
EventHandler__default['default'].off(this._element, this.constructor.EVENT_KEY);
Data__default.default.remove(this._element, this.constructor.DATA_KEY);
EventHandler__default.default.off(this._element, this.constructor.EVENT_KEY);
Object.getOwnPropertyNames(this).forEach((propertyName) => {
this[propertyName] = null;
});
}
_queueCallback(callback, element, isAnimated = true) {
if (!isAnimated) {
execute(callback);
return;
}
const transitionDuration = getTransitionDurationFromElement(element);
EventHandler__default['default'].one(element, 'transitionend', () => execute(callback));
emulateTransitionEnd(element, transitionDuration);
executeAfterTransition(callback, element, isAnimated);
}
/** Static */
static getInstance(element) {
return Data__default['default'].get(element, this.DATA_KEY);
return Data__default.default.get(getElement(element), this.DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
static get VERSION() {

File diff suppressed because one or more lines are too long

View File

@ -1,40 +1,30 @@
/*!
* Bootstrap button.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap button.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/selector-engine.js'),
require('./dom/data.js'),
require('./dom/event-handler.js'),
require('./base-component.js')
))
? (module.exports = factory(require('./dom/event-handler.js'), require('./base-component.js')))
: typeof define === 'function' && define.amd
? define([
'./dom/selector-engine',
'./dom/data',
'./dom/event-handler',
'./base-component',
], factory)
? define(['./dom/event-handler', './base-component'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Button = factory(
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Base
)));
})(this, function (SelectorEngine, Data, EventHandler, BaseComponent) {
(global.Button = factory(global.EventHandler, global.Base)));
})(this, function (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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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 getjQuery = () => {
const { jQuery } = window;
@ -46,9 +36,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -75,7 +74,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): button.js
* Bootstrap (v5.1.3): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -98,7 +97,7 @@
* ------------------------------------------------------------------------
*/
class Button extends BaseComponent__default['default'] {
class Button extends BaseComponent__default.default {
// Getters
static get NAME() {
return NAME;
@ -111,11 +110,7 @@
static jQueryInterface(config) {
return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY);
if (!data) {
data = new Button(this);
}
const data = Button.getOrCreateInstance(this);
if (config === 'toggle') {
data[config]();
@ -129,19 +124,14 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
(event) => {
event.preventDefault();
const button = event.target.closest(SELECTOR_DATA_TOGGLE);
let data = Data__default['default'].get(button, DATA_KEY);
if (!data) {
data = new Button(button);
}
const data = Button.getOrCreateInstance(button);
data.toggle();
}
);

File diff suppressed because one or more lines are too long

View File

@ -1,46 +1,45 @@
/*!
* Bootstrap carousel.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap carousel.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/selector-engine.js'),
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/selector-engine',
'./dom/data',
'./dom/event-handler',
'./dom/manipulator',
'./base-component',
], factory)
? define(
['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Carousel = factory(
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (SelectorEngine, Data, EventHandler, Manipulator, BaseComponent) {
})(this, function (EventHandler, Manipulator, SelectorEngine, 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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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 TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
const toType = (obj) => {
@ -113,24 +112,25 @@
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
/**
* 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 { jQuery } = window;
@ -142,9 +142,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -170,10 +179,36 @@
}
});
};
/**
* Return the previous/next element of a list.
*
* @param {array} list The list of elements
* @param activeElement The active element
* @param shouldGetNext Choose to get next or previous element
* @param isCycleAllowed
* @return {Element|elem} The proper element
*/
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
if (index === -1) {
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
}
const listLength = list.length;
index += shouldGetNext ? 1 : -1;
if (isCycleAllowed) {
index = (index + listLength) % listLength;
}
return list[Math.max(0, Math.min(index, listLength - 1))];
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): carousel.js
* Bootstrap (v5.1.3): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -212,6 +247,10 @@
const ORDER_PREV = 'prev';
const DIRECTION_LEFT = 'left';
const DIRECTION_RIGHT = 'right';
const KEY_TO_DIRECTION = {
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
[ARROW_RIGHT_KEY]: DIRECTION_LEFT,
};
const EVENT_SLIDE = `slide${EVENT_KEY}`;
const EVENT_SLID = `slid${EVENT_KEY}`;
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
@ -250,7 +289,7 @@
* ------------------------------------------------------------------------
*/
class Carousel extends BaseComponent__default['default'] {
class Carousel extends BaseComponent__default.default {
constructor(element, config) {
super(element);
this._items = null;
@ -262,7 +301,7 @@
this.touchStartX = 0;
this.touchDeltaX = 0;
this._config = this._getConfig(config);
this._indicatorsElement = SelectorEngine__default['default'].findOne(
this._indicatorsElement = SelectorEngine__default.default.findOne(
SELECTOR_INDICATORS,
this._element
);
@ -282,10 +321,8 @@
} // Public
next() {
if (!this._isSliding) {
this._slide(ORDER_NEXT);
}
}
nextWhenVisible() {
// Don't call next when the page isn't visible
@ -296,17 +333,15 @@
}
prev() {
if (!this._isSliding) {
this._slide(ORDER_PREV);
}
}
pause(event) {
if (!event) {
this._isPaused = true;
}
if (SelectorEngine__default['default'].findOne(SELECTOR_NEXT_PREV, this._element)) {
if (SelectorEngine__default.default.findOne(SELECTOR_NEXT_PREV, this._element)) {
triggerTransitionEnd(this._element);
this.cycle(true);
}
@ -336,7 +371,7 @@
}
to(index) {
this._activeElement = SelectorEngine__default['default'].findOne(
this._activeElement = SelectorEngine__default.default.findOne(
SELECTOR_ACTIVE_ITEM,
this._element
);
@ -348,7 +383,7 @@
}
if (this._isSliding) {
EventHandler__default['default'].one(this._element, EVENT_SLID, () => this.to(index));
EventHandler__default.default.one(this._element, EVENT_SLID, () => this.to(index));
return;
}
@ -364,7 +399,11 @@
} // Private
_getConfig(config) {
config = { ...Default, ...config };
config = {
...Default,
...Manipulator__default.default.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
}
@ -388,16 +427,16 @@
_addEventListeners() {
if (this._config.keyboard) {
EventHandler__default['default'].on(this._element, EVENT_KEYDOWN, (event) =>
EventHandler__default.default.on(this._element, EVENT_KEYDOWN, (event) =>
this._keydown(event)
);
}
if (this._config.pause === 'hover') {
EventHandler__default['default'].on(this._element, EVENT_MOUSEENTER, (event) =>
EventHandler__default.default.on(this._element, EVENT_MOUSEENTER, (event) =>
this.pause(event)
);
EventHandler__default['default'].on(this._element, EVENT_MOUSELEAVE, (event) =>
EventHandler__default.default.on(this._element, EVENT_MOUSELEAVE, (event) =>
this.cycle(event)
);
}
@ -408,11 +447,15 @@
}
_addTouchEventListeners() {
const start = (event) => {
if (
const hasPointerPenTouch = (event) => {
return (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
);
};
const start = (event) => {
if (hasPointerPenTouch(event)) {
this.touchStartX = event.clientX;
} else if (!this._pointerEvent) {
this.touchStartX = event.touches[0].clientX;
@ -428,10 +471,7 @@
};
const end = (event) => {
if (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
if (hasPointerPenTouch(event)) {
this.touchDeltaX = event.clientX - this.touchStartX;
}
@ -458,25 +498,21 @@
}
};
SelectorEngine__default['default']
.find(SELECTOR_ITEM_IMG, this._element)
.forEach((itemImg) => {
EventHandler__default['default'].on(itemImg, EVENT_DRAG_START, (e) => e.preventDefault());
SelectorEngine__default.default.find(SELECTOR_ITEM_IMG, this._element).forEach((itemImg) => {
EventHandler__default.default.on(itemImg, EVENT_DRAG_START, (event) =>
event.preventDefault()
);
});
if (this._pointerEvent) {
EventHandler__default['default'].on(this._element, EVENT_POINTERDOWN, (event) =>
start(event)
);
EventHandler__default['default'].on(this._element, EVENT_POINTERUP, (event) => end(event));
EventHandler__default.default.on(this._element, EVENT_POINTERDOWN, (event) => start(event));
EventHandler__default.default.on(this._element, EVENT_POINTERUP, (event) => end(event));
this._element.classList.add(CLASS_NAME_POINTER_EVENT);
} else {
EventHandler__default['default'].on(this._element, EVENT_TOUCHSTART, (event) =>
start(event)
);
EventHandler__default['default'].on(this._element, EVENT_TOUCHMOVE, (event) => move(event));
EventHandler__default['default'].on(this._element, EVENT_TOUCHEND, (event) => end(event));
EventHandler__default.default.on(this._element, EVENT_TOUCHSTART, (event) => start(event));
EventHandler__default.default.on(this._element, EVENT_TOUCHMOVE, (event) => move(event));
EventHandler__default.default.on(this._element, EVENT_TOUCHEND, (event) => end(event));
}
}
@ -485,52 +521,36 @@
return;
}
if (event.key === ARROW_LEFT_KEY) {
const direction = KEY_TO_DIRECTION[event.key];
if (direction) {
event.preventDefault();
this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault();
this._slide(DIRECTION_LEFT);
this._slide(direction);
}
}
_getItemIndex(element) {
this._items =
element && element.parentNode
? SelectorEngine__default['default'].find(SELECTOR_ITEM, element.parentNode)
? SelectorEngine__default.default.find(SELECTOR_ITEM, element.parentNode)
: [];
return this._items.indexOf(element);
}
_getItemByOrder(order, activeElement) {
const isNext = order === ORDER_NEXT;
const isPrev = order === ORDER_PREV;
const activeIndex = this._getItemIndex(activeElement);
const lastItemIndex = this._items.length - 1;
const isGoingToWrap =
(isPrev && activeIndex === 0) || (isNext && activeIndex === lastItemIndex);
if (isGoingToWrap && !this._config.wrap) {
return activeElement;
}
const delta = isPrev ? -1 : 1;
const itemIndex = (activeIndex + delta) % this._items.length;
return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);
}
_triggerSlideEvent(relatedTarget, eventDirectionName) {
const targetIndex = this._getItemIndex(relatedTarget);
const fromIndex = this._getItemIndex(
SelectorEngine__default['default'].findOne(SELECTOR_ACTIVE_ITEM, this._element)
SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element)
);
return EventHandler__default['default'].trigger(this._element, EVENT_SLIDE, {
return EventHandler__default.default.trigger(this._element, EVENT_SLIDE, {
relatedTarget,
direction: eventDirectionName,
from: fromIndex,
@ -540,13 +560,13 @@
_setActiveIndicatorElement(element) {
if (this._indicatorsElement) {
const activeIndicator = SelectorEngine__default['default'].findOne(
const activeIndicator = SelectorEngine__default.default.findOne(
SELECTOR_ACTIVE,
this._indicatorsElement
);
activeIndicator.classList.remove(CLASS_NAME_ACTIVE);
activeIndicator.removeAttribute('aria-current');
const indicators = SelectorEngine__default['default'].find(
const indicators = SelectorEngine__default.default.find(
SELECTOR_INDICATOR,
this._indicatorsElement
);
@ -567,7 +587,7 @@
_updateInterval() {
const element =
this._activeElement ||
SelectorEngine__default['default'].findOne(SELECTOR_ACTIVE_ITEM, this._element);
SelectorEngine__default.default.findOne(SELECTOR_ACTIVE_ITEM, this._element);
if (!element) {
return;
@ -586,7 +606,7 @@
_slide(directionOrOrder, element) {
const order = this._directionToOrder(directionOrOrder);
const activeElement = SelectorEngine__default['default'].findOne(
const activeElement = SelectorEngine__default.default.findOne(
SELECTOR_ACTIVE_ITEM,
this._element
);
@ -609,6 +629,10 @@
return;
}
if (this._isSliding) {
return;
}
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
if (slideEvent.defaultPrevented) {
@ -631,7 +655,7 @@
this._activeElement = nextElement;
const triggerSlidEvent = () => {
EventHandler__default['default'].trigger(this._element, EVENT_SLID, {
EventHandler__default.default.trigger(this._element, EVENT_SLID, {
relatedTarget: nextElement,
direction: eventDirectionName,
from: activeElementIndex,
@ -691,8 +715,8 @@
} // Static
static carouselInterface(element, config) {
let data = Data__default['default'].get(element, DATA_KEY);
let _config = { ...Default, ...Manipulator__default['default'].getDataAttributes(element) };
const data = Carousel.getOrCreateInstance(element, config);
let { _config } = data;
if (typeof config === 'object') {
_config = { ..._config, ...config };
@ -700,10 +724,6 @@
const action = typeof config === 'string' ? config : _config.slide;
if (!data) {
data = new Carousel(element, _config);
}
if (typeof config === 'number') {
data.to(config);
} else if (typeof action === 'string') {
@ -732,8 +752,8 @@
}
const config = {
...Manipulator__default['default'].getDataAttributes(target),
...Manipulator__default['default'].getDataAttributes(this),
...Manipulator__default.default.getDataAttributes(target),
...Manipulator__default.default.getDataAttributes(this),
};
const slideIndex = this.getAttribute('data-bs-slide-to');
@ -744,7 +764,7 @@
Carousel.carouselInterface(target, config);
if (slideIndex) {
Data__default['default'].get(target, DATA_KEY).to(slideIndex);
Carousel.getInstance(target).to(slideIndex);
}
event.preventDefault();
@ -756,20 +776,17 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_SLIDE,
Carousel.dataApiClickHandler
);
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => {
const carousels = SelectorEngine__default['default'].find(SELECTOR_DATA_RIDE);
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
const carousels = SelectorEngine__default.default.find(SELECTOR_DATA_RIDE);
for (let i = 0, len = carousels.length; i < len; i++) {
Carousel.carouselInterface(
carousels[i],
Data__default['default'].get(carousels[i], DATA_KEY)
);
Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));
}
});
/**

File diff suppressed because one or more lines are too long

View File

@ -1,45 +1,54 @@
/*!
* Bootstrap collapse.js v5.0.1 (https://getbootstrap.com/)
* 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/selector-engine.js'),
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/selector-engine',
? define(
[
'./dom/data',
'./dom/event-handler',
'./dom/manipulator',
'./dom/selector-engine',
'./base-component',
], factory)
],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Collapse = factory(
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (SelectorEngine, Data, EventHandler, Manipulator, BaseComponent) {
})(this, function (Data, EventHandler, Manipulator, SelectorEngine, 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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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) {
@ -109,7 +118,7 @@
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine__default['default'].findOne(obj);
return document.querySelector(obj);
}
return null;
@ -128,8 +137,19 @@
}
});
};
/**
* 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 { jQuery } = window;
@ -141,9 +161,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -170,7 +199,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): collapse.js
* Bootstrap (v5.1.3): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -186,11 +215,11 @@
const DATA_API_KEY = '.data-api';
const Default = {
toggle: true,
parent: '',
parent: null,
};
const DefaultType = {
toggle: 'boolean',
parent: '(string|element)',
parent: '(null|element)',
};
const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
@ -201,9 +230,11 @@
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 = '.show, .collapsing';
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]';
/**
* ------------------------------------------------------------------------
@ -211,21 +242,18 @@
* ------------------------------------------------------------------------
*/
class Collapse extends BaseComponent__default['default'] {
class Collapse extends BaseComponent__default.default {
constructor(element, config) {
super(element);
this._isTransitioning = false;
this._config = this._getConfig(config);
this._triggerArray = SelectorEngine__default['default'].find(
`${SELECTOR_DATA_TOGGLE}[href="#${this._element.id}"],` +
`${SELECTOR_DATA_TOGGLE}[data-bs-target="#${this._element.id}"]`
);
const toggleList = SelectorEngine__default['default'].find(SELECTOR_DATA_TOGGLE);
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']
const filterElement = SelectorEngine__default.default
.find(selector)
.filter((foundElem) => foundElem === this._element);
@ -236,10 +264,10 @@
}
}
this._parent = this._config.parent ? this._getParent() : null;
this._initializeChildren();
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray);
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
}
if (this._config.toggle) {
@ -256,7 +284,7 @@
} // Public
toggle() {
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isShown()) {
this.hide();
} else {
this.show();
@ -264,59 +292,51 @@
}
show() {
if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || this._isShown()) {
return;
}
let actives;
let actives = [];
let activesData;
if (this._parent) {
actives = SelectorEngine__default['default']
.find(SELECTOR_ACTIVES, this._parent)
.filter((elem) => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-bs-parent') === this._config.parent;
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
}
return elem.classList.contains(CLASS_NAME_COLLAPSE);
});
const container = SelectorEngine__default.default.findOne(this._selector);
if (actives.length === 0) {
actives = null;
}
}
const container = SelectorEngine__default['default'].findOne(this._selector);
if (actives) {
if (actives.length) {
const tempActiveData = actives.find((elem) => container !== elem);
activesData = tempActiveData
? Data__default['default'].get(tempActiveData, DATA_KEY)
: null;
activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;
if (activesData && activesData._isTransitioning) {
return;
}
}
const startEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW);
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW);
if (startEvent.defaultPrevented) {
return;
}
if (actives) {
actives.forEach((elemActive) => {
if (container !== elemActive) {
Collapse.collapseInterface(elemActive, 'hide');
Collapse.getOrCreateInstance(elemActive, {
toggle: false,
}).hide();
}
if (!activesData) {
Data__default['default'].set(elemActive, DATA_KEY, null);
Data__default.default.set(elemActive, DATA_KEY, null);
}
});
}
const dimension = this._getDimension();
@ -326,23 +346,19 @@
this._element.style[dimension] = 0;
if (this._triggerArray.length) {
this._triggerArray.forEach((element) => {
element.classList.remove(CLASS_NAME_COLLAPSED);
element.setAttribute('aria-expanded', true);
});
}
this._addAriaAndCollapsedClass(this._triggerArray, true);
this.setTransitioning(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] = '';
this.setTransitioning(false);
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN);
EventHandler__default.default.trigger(this._element, EVENT_SHOWN);
};
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
@ -354,11 +370,11 @@
}
hide() {
if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || !this._isShown()) {
return;
}
const startEvent = EventHandler__default['default'].trigger(this._element, EVENT_HIDE);
const startEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
if (startEvent.defaultPrevented) {
return;
@ -375,28 +391,25 @@
const triggerArrayLength = this._triggerArray.length;
if (triggerArrayLength > 0) {
for (let i = 0; i < triggerArrayLength; i++) {
const trigger = this._triggerArray[i];
const elem = getElementFromSelector(trigger);
if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
trigger.classList.add(CLASS_NAME_COLLAPSED);
trigger.setAttribute('aria-expanded', false);
}
if (elem && !this._isShown(elem)) {
this._addAriaAndCollapsedClass([trigger], false);
}
}
this.setTransitioning(true);
this._isTransitioning = true;
const complete = () => {
this.setTransitioning(false);
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);
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
};
this._element.style[dimension] = '';
@ -404,40 +417,53 @@
this._queueCallback(complete, this._element, true);
}
setTransitioning(isTransitioning) {
this._isTransitioning = isTransitioning;
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
} // Private
_getConfig(config) {
config = { ...Default, ...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(WIDTH) ? WIDTH : HEIGHT;
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
}
_getParent() {
let { parent } = this._config;
parent = getElement(parent);
const selector = `${SELECTOR_DATA_TOGGLE}[data-bs-parent="${parent}"]`;
SelectorEngine__default['default'].find(selector, parent).forEach((element) => {
const selected = getElementFromSelector(element);
this._addAriaAndCollapsedClass(selected, [element]);
});
return parent;
}
_addAriaAndCollapsedClass(element, triggerArray) {
if (!element || !triggerArray.length) {
_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;
}
const isOpen = element.classList.contains(CLASS_NAME_SHOW);
triggerArray.forEach((elem) => {
if (isOpen) {
elem.classList.remove(CLASS_NAME_COLLAPSED);
@ -449,21 +475,15 @@
});
} // Static
static collapseInterface(element, config) {
let data = Data__default['default'].get(element, DATA_KEY);
const _config = {
...Default,
...Manipulator__default['default'].getDataAttributes(element),
...(typeof config === 'object' && config ? config : {}),
};
static jQueryInterface(config) {
return this.each(function () {
const _config = {};
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
if (typeof config === 'string' && /show|hide/.test(config)) {
_config.toggle = false;
}
if (!data) {
data = new Collapse(element, _config);
}
const data = Collapse.getOrCreateInstance(this, _config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -472,11 +492,6 @@
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Collapse.collapseInterface(this, config);
});
}
}
@ -486,7 +501,7 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
@ -499,26 +514,12 @@
event.preventDefault();
}
const triggerData = Manipulator__default['default'].getDataAttributes(this);
const selector = getSelectorFromElement(this);
const selectorElements = SelectorEngine__default['default'].find(selector);
const selectorElements = SelectorEngine__default.default.find(selector);
selectorElements.forEach((element) => {
const data = Data__default['default'].get(element, DATA_KEY);
let config;
if (data) {
// update parent attribute
if (data._parent === null && typeof triggerData.parent === 'string') {
data._config.parent = triggerData.parent;
data._parent = data._getParent();
}
config = 'toggle';
} else {
config = triggerData;
}
Collapse.collapseInterface(element, config);
Collapse.getOrCreateInstance(element, {
toggle: false,
}).toggle();
});
}
);

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap data.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap data.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)
*/
@ -15,7 +15,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/data.js
* Bootstrap (v5.1.3): dom/data.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -26,7 +26,7 @@
* ------------------------------------------------------------------------
*/
const elementMap = new Map();
var data = {
const data = {
set(element, key, instance) {
if (!elementMap.has(element)) {
elementMap.set(element, new Map());

View File

@ -1 +1 @@
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.1): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAJ,EAAnB;AAEA,aAAe;EACbC,EAAAA,GAAG,CAACC,OAAD,EAAUC,GAAV,EAAeC,QAAf,EAAyB;EAC1B,QAAI,CAACL,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5BH,MAAAA,UAAU,CAACE,GAAX,CAAeC,OAAf,EAAwB,IAAIF,GAAJ,EAAxB;EACD;;EAED,UAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB,CAL0B;EAQ1B;;EACA,QAAI,CAACI,WAAW,CAACD,GAAZ,CAAgBF,GAAhB,CAAD,IAAyBG,WAAW,CAACE,IAAZ,KAAqB,CAAlD,EAAqD;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAR,CAAe,+EAA8EC,KAAK,CAACC,IAAN,CAAWN,WAAW,CAACO,IAAZ,EAAX,EAA+B,CAA/B,CAAkC,GAA/H;EACA;EACD;;EAEDP,IAAAA,WAAW,CAACL,GAAZ,CAAgBE,GAAhB,EAAqBC,QAArB;EACD,GAjBY;;EAmBbG,EAAAA,GAAG,CAACL,OAAD,EAAUC,GAAV,EAAe;EAChB,QAAIJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAJ,EAA6B;EAC3B,aAAOH,UAAU,CAACQ,GAAX,CAAeL,OAAf,EAAwBK,GAAxB,CAA4BJ,GAA5B,KAAoC,IAA3C;EACD;;EAED,WAAO,IAAP;EACD,GAzBY;;EA2BbW,EAAAA,MAAM,CAACZ,OAAD,EAAUC,GAAV,EAAe;EACnB,QAAI,CAACJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5B;EACD;;EAED,UAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB;EAEAI,IAAAA,WAAW,CAACS,MAAZ,CAAmBZ,GAAnB,EAPmB;;EAUnB,QAAIG,WAAW,CAACE,IAAZ,KAAqB,CAAzB,EAA4B;EAC1BT,MAAAA,UAAU,CAACgB,MAAX,CAAkBb,OAAlB;EACD;EACF;;EAxCY,CAAf;;;;;;;;"}
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.3): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst elementMap = new Map()\n\nexport default {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map())\n }\n\n const instanceMap = elementMap.get(element)\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`)\n return\n }\n\n instanceMap.set(key, instance)\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null\n }\n\n return null\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return\n }\n\n const instanceMap = elementMap.get(element)\n\n instanceMap.delete(key)\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element)\n }\n }\n}\n"],"names":["elementMap","Map","set","element","key","instance","has","instanceMap","get","size","console","error","Array","from","keys","remove","delete"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EAEA,MAAMA,UAAU,GAAG,IAAIC,GAAJ,EAAnB;AAEA,eAAe;EACbC,EAAAA,GAAG,CAACC,OAAD,EAAUC,GAAV,EAAeC,QAAf,EAAyB;EAC1B,QAAI,CAACL,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5BH,MAAAA,UAAU,CAACE,GAAX,CAAeC,OAAf,EAAwB,IAAIF,GAAJ,EAAxB;EACD;;EAED,UAAMM,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB,CAL0B;EAQ1B;;EACA,QAAI,CAACI,WAAW,CAACD,GAAZ,CAAgBF,GAAhB,CAAD,IAAyBG,WAAW,CAACE,IAAZ,KAAqB,CAAlD,EAAqD;EACnD;EACAC,MAAAA,OAAO,CAACC,KAAR,CAAe,+EAA8EC,KAAK,CAACC,IAAN,CAAWN,WAAW,CAACO,IAAZ,EAAX,EAA+B,CAA/B,CAAkC,GAA/H;EACA;EACD;;EAEDP,IAAAA,WAAW,CAACL,GAAZ,CAAgBE,GAAhB,EAAqBC,QAArB;EACD,GAjBY;;EAmBbG,EAAAA,GAAG,CAACL,OAAD,EAAUC,GAAV,EAAe;EAChB,QAAIJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAJ,EAA6B;EAC3B,aAAOH,UAAU,CAACQ,GAAX,CAAeL,OAAf,EAAwBK,GAAxB,CAA4BJ,GAA5B,KAAoC,IAA3C;EACD;;EAED,WAAO,IAAP;EACD,GAzBY;;EA2BbW,EAAAA,MAAM,CAACZ,OAAD,EAAUC,GAAV,EAAe;EACnB,QAAI,CAACJ,UAAU,CAACM,GAAX,CAAeH,OAAf,CAAL,EAA8B;EAC5B;EACD;;EAED,UAAMI,WAAW,GAAGP,UAAU,CAACQ,GAAX,CAAeL,OAAf,CAApB;EAEAI,IAAAA,WAAW,CAACS,MAAZ,CAAmBZ,GAAnB,EAPmB;;EAUnB,QAAIG,WAAW,CAACE,IAAZ,KAAqB,CAAzB,EAA4B;EAC1BT,MAAAA,UAAU,CAACgB,MAAX,CAAkBb,OAAlB;EACD;EACF;;EAxCY,CAAf;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap event-handler.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap event-handler.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)
*/
@ -13,6 +13,13 @@
})(this, function () {
'use strict';
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const getjQuery = () => {
const { jQuery } = window;
@ -25,7 +32,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/event-handler.js
* Bootstrap (v5.1.3): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -133,7 +140,6 @@
event.delegateTarget = target;
if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, selector, fn);
}

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap manipulator.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap manipulator.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)
*/
@ -15,7 +15,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/manipulator.js
* Bootstrap (v5.1.3): dom/manipulator.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -75,8 +75,8 @@
offset(element) {
const rect = element.getBoundingClientRect();
return {
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft,
top: rect.top + window.pageYOffset,
left: rect.left + window.pageXOffset,
};
},

View File

@ -1 +1 @@
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.1): dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(val) {\n if (val === 'true') {\n return true\n }\n\n if (val === 'false') {\n return false\n }\n\n if (val === Number(val).toString()) {\n return Number(val)\n }\n\n if (val === '' || val === 'null') {\n return null\n }\n\n return val\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n\n Object.keys(element.dataset)\n .filter(key => key.startsWith('bs'))\n .forEach(key => {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n })\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n },\n\n offset(element) {\n const rect = element.getBoundingClientRect()\n\n return {\n top: rect.top + document.body.scrollTop,\n left: rect.left + document.body.scrollLeft\n }\n },\n\n position(element) {\n return {\n top: element.offsetTop,\n left: element.offsetLeft\n }\n }\n}\n\nexport default Manipulator\n"],"names":["normalizeData","val","Number","toString","normalizeDataKey","key","replace","chr","toLowerCase","Manipulator","setDataAttribute","element","value","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","Object","keys","dataset","filter","startsWith","forEach","pureKey","charAt","slice","length","getDataAttribute","getAttribute","offset","rect","getBoundingClientRect","top","document","body","scrollTop","left","scrollLeft","position","offsetTop","offsetLeft"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;EAEA,SAASA,aAAT,CAAuBC,GAAvB,EAA4B;EAC1B,MAAIA,GAAG,KAAK,MAAZ,EAAoB;EAClB,WAAO,IAAP;EACD;;EAED,MAAIA,GAAG,KAAK,OAAZ,EAAqB;EACnB,WAAO,KAAP;EACD;;EAED,MAAIA,GAAG,KAAKC,MAAM,CAACD,GAAD,CAAN,CAAYE,QAAZ,EAAZ,EAAoC;EAClC,WAAOD,MAAM,CAACD,GAAD,CAAb;EACD;;EAED,MAAIA,GAAG,KAAK,EAAR,IAAcA,GAAG,KAAK,MAA1B,EAAkC;EAChC,WAAO,IAAP;EACD;;EAED,SAAOA,GAAP;EACD;;EAED,SAASG,gBAAT,CAA0BC,GAA1B,EAA+B;EAC7B,SAAOA,GAAG,CAACC,OAAJ,CAAY,QAAZ,EAAsBC,GAAG,IAAK,IAAGA,GAAG,CAACC,WAAJ,EAAkB,EAAnD,CAAP;EACD;;QAEKC,WAAW,GAAG;EAClBC,EAAAA,gBAAgB,CAACC,OAAD,EAAUN,GAAV,EAAeO,KAAf,EAAsB;EACpCD,IAAAA,OAAO,CAACE,YAAR,CAAsB,WAAUT,gBAAgB,CAACC,GAAD,CAAM,EAAtD,EAAyDO,KAAzD;EACD,GAHiB;;EAKlBE,EAAAA,mBAAmB,CAACH,OAAD,EAAUN,GAAV,EAAe;EAChCM,IAAAA,OAAO,CAACI,eAAR,CAAyB,WAAUX,gBAAgB,CAACC,GAAD,CAAM,EAAzD;EACD,GAPiB;;EASlBW,EAAAA,iBAAiB,CAACL,OAAD,EAAU;EACzB,QAAI,CAACA,OAAL,EAAc;EACZ,aAAO,EAAP;EACD;;EAED,UAAMM,UAAU,GAAG,EAAnB;EAEAC,IAAAA,MAAM,CAACC,IAAP,CAAYR,OAAO,CAACS,OAApB,EACGC,MADH,CACUhB,GAAG,IAAIA,GAAG,CAACiB,UAAJ,CAAe,IAAf,CADjB,EAEGC,OAFH,CAEWlB,GAAG,IAAI;EACd,UAAImB,OAAO,GAAGnB,GAAG,CAACC,OAAJ,CAAY,KAAZ,EAAmB,EAAnB,CAAd;EACAkB,MAAAA,OAAO,GAAGA,OAAO,CAACC,MAAR,CAAe,CAAf,EAAkBjB,WAAlB,KAAkCgB,OAAO,CAACE,KAAR,CAAc,CAAd,EAAiBF,OAAO,CAACG,MAAzB,CAA5C;EACAV,MAAAA,UAAU,CAACO,OAAD,CAAV,GAAsBxB,aAAa,CAACW,OAAO,CAACS,OAAR,CAAgBf,GAAhB,CAAD,CAAnC;EACD,KANH;EAQA,WAAOY,UAAP;EACD,GAzBiB;;EA2BlBW,EAAAA,gBAAgB,CAACjB,OAAD,EAAUN,GAAV,EAAe;EAC7B,WAAOL,aAAa,CAACW,OAAO,CAACkB,YAAR,CAAsB,WAAUzB,gBAAgB,CAACC,GAAD,CAAM,EAAtD,CAAD,CAApB;EACD,GA7BiB;;EA+BlByB,EAAAA,MAAM,CAACnB,OAAD,EAAU;EACd,UAAMoB,IAAI,GAAGpB,OAAO,CAACqB,qBAAR,EAAb;EAEA,WAAO;EACLC,MAAAA,GAAG,EAAEF,IAAI,CAACE,GAAL,GAAWC,QAAQ,CAACC,IAAT,CAAcC,SADzB;EAELC,MAAAA,IAAI,EAAEN,IAAI,CAACM,IAAL,GAAYH,QAAQ,CAACC,IAAT,CAAcG;EAF3B,KAAP;EAID,GAtCiB;;EAwClBC,EAAAA,QAAQ,CAAC5B,OAAD,EAAU;EAChB,WAAO;EACLsB,MAAAA,GAAG,EAAEtB,OAAO,CAAC6B,SADR;EAELH,MAAAA,IAAI,EAAE1B,OAAO,CAAC8B;EAFT,KAAP;EAID;;EA7CiB;;;;;;;;"}
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.1.3): dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(val) {\n if (val === 'true') {\n return true\n }\n\n if (val === 'false') {\n return false\n }\n\n if (val === Number(val).toString()) {\n return Number(val)\n }\n\n if (val === '' || val === 'null') {\n return null\n }\n\n return val\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`)\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value)\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`)\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {}\n }\n\n const attributes = {}\n\n Object.keys(element.dataset)\n .filter(key => key.startsWith('bs'))\n .forEach(key => {\n let pureKey = key.replace(/^bs/, '')\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length)\n attributes[pureKey] = normalizeData(element.dataset[key])\n })\n\n return attributes\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`))\n },\n\n offset(element) {\n const rect = element.getBoundingClientRect()\n\n return {\n top: rect.top + window.pageYOffset,\n left: rect.left + window.pageXOffset\n }\n },\n\n position(element) {\n return {\n top: element.offsetTop,\n left: element.offsetLeft\n }\n }\n}\n\nexport default Manipulator\n"],"names":["normalizeData","val","Number","toString","normalizeDataKey","key","replace","chr","toLowerCase","Manipulator","setDataAttribute","element","value","setAttribute","removeDataAttribute","removeAttribute","getDataAttributes","attributes","Object","keys","dataset","filter","startsWith","forEach","pureKey","charAt","slice","length","getDataAttribute","getAttribute","offset","rect","getBoundingClientRect","top","window","pageYOffset","left","pageXOffset","position","offsetTop","offsetLeft"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;EAEA,SAASA,aAAT,CAAuBC,GAAvB,EAA4B;EAC1B,MAAIA,GAAG,KAAK,MAAZ,EAAoB;EAClB,WAAO,IAAP;EACD;;EAED,MAAIA,GAAG,KAAK,OAAZ,EAAqB;EACnB,WAAO,KAAP;EACD;;EAED,MAAIA,GAAG,KAAKC,MAAM,CAACD,GAAD,CAAN,CAAYE,QAAZ,EAAZ,EAAoC;EAClC,WAAOD,MAAM,CAACD,GAAD,CAAb;EACD;;EAED,MAAIA,GAAG,KAAK,EAAR,IAAcA,GAAG,KAAK,MAA1B,EAAkC;EAChC,WAAO,IAAP;EACD;;EAED,SAAOA,GAAP;EACD;;EAED,SAASG,gBAAT,CAA0BC,GAA1B,EAA+B;EAC7B,SAAOA,GAAG,CAACC,OAAJ,CAAY,QAAZ,EAAsBC,GAAG,IAAK,IAAGA,GAAG,CAACC,WAAJ,EAAkB,EAAnD,CAAP;EACD;;QAEKC,WAAW,GAAG;EAClBC,EAAAA,gBAAgB,CAACC,OAAD,EAAUN,GAAV,EAAeO,KAAf,EAAsB;EACpCD,IAAAA,OAAO,CAACE,YAAR,CAAsB,WAAUT,gBAAgB,CAACC,GAAD,CAAM,EAAtD,EAAyDO,KAAzD;EACD,GAHiB;;EAKlBE,EAAAA,mBAAmB,CAACH,OAAD,EAAUN,GAAV,EAAe;EAChCM,IAAAA,OAAO,CAACI,eAAR,CAAyB,WAAUX,gBAAgB,CAACC,GAAD,CAAM,EAAzD;EACD,GAPiB;;EASlBW,EAAAA,iBAAiB,CAACL,OAAD,EAAU;EACzB,QAAI,CAACA,OAAL,EAAc;EACZ,aAAO,EAAP;EACD;;EAED,UAAMM,UAAU,GAAG,EAAnB;EAEAC,IAAAA,MAAM,CAACC,IAAP,CAAYR,OAAO,CAACS,OAApB,EACGC,MADH,CACUhB,GAAG,IAAIA,GAAG,CAACiB,UAAJ,CAAe,IAAf,CADjB,EAEGC,OAFH,CAEWlB,GAAG,IAAI;EACd,UAAImB,OAAO,GAAGnB,GAAG,CAACC,OAAJ,CAAY,KAAZ,EAAmB,EAAnB,CAAd;EACAkB,MAAAA,OAAO,GAAGA,OAAO,CAACC,MAAR,CAAe,CAAf,EAAkBjB,WAAlB,KAAkCgB,OAAO,CAACE,KAAR,CAAc,CAAd,EAAiBF,OAAO,CAACG,MAAzB,CAA5C;EACAV,MAAAA,UAAU,CAACO,OAAD,CAAV,GAAsBxB,aAAa,CAACW,OAAO,CAACS,OAAR,CAAgBf,GAAhB,CAAD,CAAnC;EACD,KANH;EAQA,WAAOY,UAAP;EACD,GAzBiB;;EA2BlBW,EAAAA,gBAAgB,CAACjB,OAAD,EAAUN,GAAV,EAAe;EAC7B,WAAOL,aAAa,CAACW,OAAO,CAACkB,YAAR,CAAsB,WAAUzB,gBAAgB,CAACC,GAAD,CAAM,EAAtD,CAAD,CAApB;EACD,GA7BiB;;EA+BlByB,EAAAA,MAAM,CAACnB,OAAD,EAAU;EACd,UAAMoB,IAAI,GAAGpB,OAAO,CAACqB,qBAAR,EAAb;EAEA,WAAO;EACLC,MAAAA,GAAG,EAAEF,IAAI,CAACE,GAAL,GAAWC,MAAM,CAACC,WADlB;EAELC,MAAAA,IAAI,EAAEL,IAAI,CAACK,IAAL,GAAYF,MAAM,CAACG;EAFpB,KAAP;EAID,GAtCiB;;EAwClBC,EAAAA,QAAQ,CAAC3B,OAAD,EAAU;EAChB,WAAO;EACLsB,MAAAA,GAAG,EAAEtB,OAAO,CAAC4B,SADR;EAELH,MAAAA,IAAI,EAAEzB,OAAO,CAAC6B;EAFT,KAAP;EAID;;EA7CiB;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap selector-engine.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap selector-engine.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)
*/
@ -15,15 +15,52 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/selector-engine.js
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const isElement = (obj) => {
if (!obj || typeof obj !== 'object') {
return false;
}
if (typeof obj.jquery !== 'undefined') {
obj = obj[0];
}
return typeof obj.nodeType !== 'undefined';
};
const isVisible = (element) => {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
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';
};
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const NODE_TEXT = 3;
const SelectorEngine = {
@ -85,6 +122,22 @@
return [];
},
focusableChildren(element) {
const focusables = [
'a',
'button',
'input',
'textarea',
'select',
'details',
'[tabindex]',
'[contenteditable="true"]',
]
.map((selector) => `${selector}:not([tabindex^="-"])`)
.join(', ');
return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el));
},
};
return SelectorEngine;

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap dropdown.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap dropdown.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,44 +7,43 @@
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(
require('@popperjs/core'),
require('./dom/selector-engine.js'),
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([
? define(
[
'@popperjs/core',
'./dom/selector-engine',
'./dom/data',
'./dom/event-handler',
'./dom/manipulator',
'./dom/selector-engine',
'./base-component',
], factory)
],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Dropdown = factory(
global.Popper,
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (Popper, SelectorEngine, Data, EventHandler, Manipulator, BaseComponent) {
})(this, function (Popper, EventHandler, Manipulator, SelectorEngine, 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 };
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
const n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
for (const k in e) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(
n,
k,
@ -52,24 +51,28 @@
? d
: {
enumerable: true,
get: function () {
return e[k];
},
get: () => e[k],
}
);
}
});
}
n['default'] = e;
}
n.default = e;
return Object.freeze(n);
}
var Popper__namespace = /*#__PURE__*/ _interopNamespace(Popper);
var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine);
var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
const Popper__namespace = /*#__PURE__*/ _interopNamespace(Popper);
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) {
@ -129,7 +132,7 @@
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine__default['default'].findOne(obj);
return document.querySelector(obj);
}
return null;
@ -150,21 +153,11 @@
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
const isDisabled = (element) => {
@ -195,9 +188,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -223,10 +225,36 @@
}
});
};
/**
* Return the previous/next element of a list.
*
* @param {array} list The list of elements
* @param activeElement The active element
* @param shouldGetNext Choose to get next or previous element
* @param isCycleAllowed
* @return {Element|elem} The proper element
*/
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
if (index === -1) {
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
}
const listLength = list.length;
index += shouldGetNext ? 1 : -1;
if (isCycleAllowed) {
index = (index + listLength) % listLength;
}
return list[Math.max(0, Math.min(index, listLength - 1))];
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dropdown.js
* Bootstrap (v5.1.3): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -252,7 +280,6 @@
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const EVENT_CLICK = `click${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
@ -293,15 +320,13 @@
* ------------------------------------------------------------------------
*/
class Dropdown extends BaseComponent__default['default'] {
class Dropdown extends BaseComponent__default.default {
constructor(element, config) {
super(element);
this._popper = null;
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._inNavbar = this._detectNavbar();
this._addEventListeners();
} // Getters
static get Default() {
@ -317,30 +342,18 @@
} // Public
toggle() {
if (isDisabled(this._element)) {
return;
}
const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
if (isActive) {
this.hide();
return;
}
this.show();
return this._isShown() ? this.hide() : this.show();
}
show() {
if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || this._isShown(this._menu)) {
return;
}
const parent = Dropdown.getParentFromElement(this._element);
const relatedTarget = {
relatedTarget: this._element,
};
const showEvent = EventHandler__default['default'].trigger(
const showEvent = EventHandler__default.default.trigger(
this._element,
EVENT_SHOW,
relatedTarget
@ -348,35 +361,14 @@
if (showEvent.defaultPrevented) {
return;
} // Totally disable Popper for Dropdowns in Navbar
}
const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar
if (this._inNavbar) {
Manipulator__default['default'].setDataAttribute(this._menu, 'popper', 'none');
Manipulator__default.default.setDataAttribute(this._menu, 'popper', 'none');
} else {
if (typeof Popper__namespace === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator__default['default'].setDataAttribute(this._menu, 'popper', 'static');
}
this._createPopper(parent);
} // If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
// only needed because of broken event delegation on iOS
@ -385,22 +377,22 @@
if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler__default['default'].on(elem, 'mouseover', noop));
.forEach((elem) => EventHandler__default.default.on(elem, 'mouseover', noop));
}
this._element.focus();
this._element.setAttribute('aria-expanded', true);
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._menu.classList.add(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, relatedTarget);
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, relatedTarget);
}
hide() {
if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || !this._isShown(this._menu)) {
return;
}
@ -427,15 +419,8 @@
}
} // Private
_addEventListeners() {
EventHandler__default['default'].on(this._element, EVENT_CLICK, (event) => {
event.preventDefault();
this.toggle();
});
}
_completeHide(relatedTarget) {
const hideEvent = EventHandler__default['default'].trigger(
const hideEvent = EventHandler__default.default.trigger(
this._element,
EVENT_HIDE,
relatedTarget
@ -449,7 +434,7 @@
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler__default['default'].off(elem, 'mouseover', noop));
.forEach((elem) => EventHandler__default.default.off(elem, 'mouseover', noop));
}
if (this._popper) {
@ -462,14 +447,14 @@
this._element.setAttribute('aria-expanded', 'false');
Manipulator__default['default'].removeDataAttribute(this._menu, 'popper');
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN, relatedTarget);
Manipulator__default.default.removeDataAttribute(this._menu, 'popper');
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN, relatedTarget);
}
_getConfig(config) {
config = {
...this.constructor.Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...Manipulator__default.default.getDataAttributes(this._element),
...config,
};
typeCheckConfig(NAME, config, this.constructor.DefaultType);
@ -488,8 +473,39 @@
return config;
}
_createPopper(parent) {
if (typeof Popper__namespace === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator__default.default.setDataAttribute(this._menu, 'popper', 'static');
}
}
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
}
_getMenuElement() {
return SelectorEngine__default['default'].next(this._element, SELECTOR_MENU)[0];
return SelectorEngine__default.default.next(this._element, SELECTOR_MENU)[0];
}
_getPlacement() {
@ -566,50 +582,32 @@
};
}
_selectMenuItem(event) {
const items = SelectorEngine__default['default']
_selectMenuItem({ key, target }) {
const items = SelectorEngine__default.default
.find(SELECTOR_VISIBLE_ITEMS, this._menu)
.filter(isVisible);
if (!items.length) {
return;
}
} // if target isn't included in items (e.g. when expanding the dropdown)
// allow cycling to get the last item in case key equals ARROW_UP_KEY
let index = items.indexOf(event.target); // Up
if (event.key === ARROW_UP_KEY && index > 0) {
index--;
} // Down
if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
index++;
} // index is -1 if the first keydown is an ArrowUp
index = index === -1 ? 0 : index;
items[index].focus();
getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
} // Static
static dropdownInterface(element, config) {
let data = Data__default['default'].get(element, DATA_KEY);
static jQueryInterface(config) {
return this.each(function () {
const data = Dropdown.getOrCreateInstance(this, config);
const _config = typeof config === 'object' ? config : null;
if (!data) {
data = new Dropdown(element, _config);
if (typeof config !== 'string') {
return;
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`);
}
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Dropdown.dropdownInterface(this, config);
});
}
@ -621,16 +619,16 @@
return;
}
const toggles = SelectorEngine__default['default'].find(SELECTOR_DATA_TOGGLE);
const toggles = SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE);
for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data__default['default'].get(toggles[i], DATA_KEY);
const context = Dropdown.getInstance(toggles[i]);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
if (!context._isShown()) {
continue;
}
@ -703,28 +701,29 @@
return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE)
? this
: SelectorEngine__default['default'].prev(this, SELECTOR_DATA_TOGGLE)[0];
: SelectorEngine__default.default.prev(this, SELECTOR_DATA_TOGGLE)[0];
const instance = Dropdown.getOrCreateInstance(getToggleButton);
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus();
instance.hide();
return;
}
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
getToggleButton().click();
if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
if (!isActive) {
instance.show();
}
instance._selectMenuItem(event);
return;
}
if (!isActive || event.key === SPACE_KEY) {
Dropdown.clearMenus();
return;
}
Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
}
}
/**
@ -733,27 +732,27 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_KEYDOWN_DATA_API,
SELECTOR_DATA_TOGGLE,
Dropdown.dataApiKeydownHandler
);
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_KEYDOWN_DATA_API,
SELECTOR_MENU,
Dropdown.dataApiKeydownHandler
);
EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
EventHandler__default['default'].on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
EventHandler__default['default'].on(
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
EventHandler__default.default.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
function (event) {
event.preventDefault();
Dropdown.dropdownInterface(this);
Dropdown.getOrCreateInstance(this).toggle();
}
);
/**

File diff suppressed because one or more lines are too long

View File

@ -1,42 +1,45 @@
/*!
* Bootstrap modal.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap modal.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/selector-engine.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/selector-engine',
'./dom/event-handler',
'./dom/manipulator',
'./base-component',
], factory)
? define(
['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Modal = factory(
global.SelectorEngine,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (SelectorEngine, EventHandler, Manipulator, BaseComponent) {
})(this, function (EventHandler, Manipulator, SelectorEngine, 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 EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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 MILLISECONDS_MULTIPLIER = 1000;
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
@ -116,22 +119,17 @@
return typeof obj.nodeType !== 'undefined';
};
const emulateTransitionEnd = (element, duration) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true;
element.removeEventListener(TRANSITION_END, listener);
const getElement = (obj) => {
if (isElement(obj)) {
// it's a jQuery object or a node element
return obj.jquery ? obj[0] : obj;
}
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
triggerTransitionEnd(element);
if (typeof obj === 'string' && obj.length > 0) {
return document.querySelector(obj);
}
}, emulatedDuration);
return null;
};
const typeCheckConfig = (componentName, config, configTypes) => {
@ -149,24 +147,41 @@
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
const reflow = (element) => element.offsetHeight;
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';
};
/**
* 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;
@ -178,9 +193,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -213,111 +237,173 @@
}
};
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);
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/scrollBar.js
* Bootstrap (v5.1.3): util/scrollBar.js
* 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 = () => {
class ScrollBarHelper {
constructor() {
this._element = document.body;
}
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
hide() {
const width = this.getWidth();
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
_setElementAttributes(
this._setElementAttributes(
this._element,
'paddingRight',
(calculatedValue) => calculatedValue + width
); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
this._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';
};
_disableOverFlow() {
this._saveInitialAttribute(this._element, 'overflow');
const _setElementAttributes = (selector, styleProp, callback) => {
const scrollbarWidth = getWidth();
SelectorEngine__default['default'].find(selector).forEach((element) => {
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
this._element.style.overflow = 'hidden';
}
_setElementAttributes(selector, styleProp, callback) {
const scrollbarWidth = this.getWidth();
const manipulationCallBack = (element) => {
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return;
}
const actualValue = element.style[styleProp];
this._saveInitialAttribute(element, 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');
this._applyManipulationCallback(selector, manipulationCallBack);
}
_resetElementAttributes('body', 'paddingRight');
reset() {
this._resetElementAttributes(this._element, 'overflow');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
this._resetElementAttributes(this._element, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
};
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine__default['default'].find(selector).forEach((element) => {
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
}
_saveInitialAttribute(element, styleProp) {
const actualValue = element.style[styleProp];
if (actualValue) {
Manipulator__default.default.setDataAttribute(element, styleProp, actualValue);
}
}
_resetElementAttributes(selector, styleProp) {
const manipulationCallBack = (element) => {
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;
}
});
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
_applyManipulationCallback(selector, callBack) {
if (isElement(selector)) {
callBack(selector);
} else {
SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
}
}
isOverflowing() {
return this.getWidth() > 0;
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): 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,
rootElement: document.body,
rootElement: 'body',
// 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',
rootElement: '(element|string)',
clickCallback: '(function|null)',
};
const NAME$1 = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const NAME$2 = 'backdrop';
const CLASS_NAME_FADE$1 = '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) {
@ -362,7 +448,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$1);
@ -375,9 +461,10 @@
}
_getConfig(config) {
config = { ...Default$1, ...(typeof config === 'object' ? config : {}) };
config.rootElement = config.rootElement || document.body;
typeCheckConfig(NAME$1, config, DefaultType$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$2, config, DefaultType$2);
return config;
}
@ -386,9 +473,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;
@ -399,30 +486,148 @@
return;
}
EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._element.remove();
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);
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): modal.js
* 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): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -452,7 +657,6 @@
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}`;
@ -463,25 +667,27 @@
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_STATIC = 'modal-static';
const OPEN_SELECTOR = '.modal.show';
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"]';
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Modal extends BaseComponent__default['default'] {
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);
this._dialog = SelectorEngine__default.default.findOne(SELECTOR_DIALOG, this._element);
this._backdrop = this._initializeBackDrop();
this._focustrap = this._initializeFocusTrap();
this._isShown = false;
this._ignoreBackdropClick = false;
this._isTransitioning = false;
this._scrollBar = new ScrollBarHelper();
} // Getters
static get Default() {
@ -501,20 +707,22 @@
return;
}
if (this._isAnimated()) {
this._isTransitioning = true;
}
const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, {
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
relatedTarget,
});
if (this._isShown || showEvent.defaultPrevented) {
if (showEvent.defaultPrevented) {
return;
}
this._isShown = true;
hide();
if (this._isAnimated()) {
this._isTransitioning = true;
}
this._scrollBar.hide();
document.body.classList.add(CLASS_NAME_OPEN);
this._adjustDialog();
@ -523,14 +731,8 @@
this._setResizeEvent();
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) => {
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;
}
@ -540,16 +742,12 @@
this._showBackdrop(() => this._showElement(relatedTarget));
}
hide(event) {
if (event) {
event.preventDefault();
}
hide() {
if (!this._isShown || this._isTransitioning) {
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;
@ -567,31 +765,26 @@
this._setResizeEvent();
EventHandler__default['default'].off(document, EVENT_FOCUSIN);
this._focustrap.deactivate();
this._element.classList.remove(CLASS_NAME_SHOW);
EventHandler__default['default'].off(this._element, EVENT_CLICK_DISMISS);
EventHandler__default['default'].off(this._dialog, EVENT_MOUSEDOWN_DISMISS);
EventHandler__default.default.off(this._element, EVENT_CLICK_DISMISS);
EventHandler__default.default.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);
this._queueCallback(() => this._hideModal(), this._element, isAnimated);
}
dispose() {
[window, this._dialog].forEach((htmlElement) =>
EventHandler__default['default'].off(htmlElement, EVENT_KEY)
EventHandler__default.default.off(htmlElement, EVENT_KEY)
);
this._backdrop.dispose();
super.dispose();
/**
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
* Do not move `document` in `htmlElements` array
* It will remove `EVENT_CLICK_DATA_API` event that should remain
*/
this._focustrap.deactivate();
EventHandler__default['default'].off(document, EVENT_FOCUSIN);
super.dispose();
}
handleUpdate() {
@ -606,11 +799,17 @@
});
}
_initializeFocusTrap() {
return new FocusTrap({
trapElement: this._element,
});
}
_getConfig(config) {
config = {
...Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...config,
...Manipulator__default.default.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
@ -619,14 +818,11 @@
_showElement(relatedTarget) {
const isAnimated = this._isAnimated();
const modalBody = SelectorEngine__default['default'].findOne(
SELECTOR_MODAL_BODY,
this._dialog
);
const modalBody = SelectorEngine__default.default.findOne(SELECTOR_MODAL_BODY, this._dialog);
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
// Don't move modal's DOM position
document.body.appendChild(this._element);
document.body.append(this._element);
}
this._element.style.display = 'block';
@ -649,17 +845,13 @@
this._element.classList.add(CLASS_NAME_SHOW);
if (this._config.focus) {
this._enforceFocus();
}
const transitionComplete = () => {
if (this._config.focus) {
this._element.focus();
this._focustrap.activate();
}
this._isTransitioning = false;
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, {
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
relatedTarget,
});
};
@ -667,23 +859,9 @@
this._queueCallback(transitionComplete, this._dialog, isAnimated);
}
_enforceFocus() {
EventHandler__default['default'].off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler__default['default'].on(document, EVENT_FOCUSIN, (event) => {
if (
document !== event.target &&
this._element !== event.target &&
!this._element.contains(event.target)
) {
this._element.focus();
}
});
}
_setEscapeEvent() {
if (this._isShown) {
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) {
event.preventDefault();
this.hide();
@ -692,15 +870,15 @@
}
});
} else {
EventHandler__default['default'].off(this._element, EVENT_KEYDOWN_DISMISS);
EventHandler__default.default.off(this._element, EVENT_KEYDOWN_DISMISS);
}
}
_setResizeEvent() {
if (this._isShown) {
EventHandler__default['default'].on(window, EVENT_RESIZE, () => this._adjustDialog());
EventHandler__default.default.on(window, EVENT_RESIZE, () => this._adjustDialog());
} else {
EventHandler__default['default'].off(window, EVENT_RESIZE);
EventHandler__default.default.off(window, EVENT_RESIZE);
}
}
@ -720,13 +898,14 @@
this._resetAdjustments();
reset();
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
this._scrollBar.reset();
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
});
}
_showBackdrop(callback) {
EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, (event) => {
EventHandler__default.default.on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false;
return;
@ -751,36 +930,37 @@
}
_triggerBackdropTransition() {
const hideEvent = EventHandler__default['default'].trigger(
this._element,
EVENT_HIDE_PREVENTED
);
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE_PREVENTED);
if (hideEvent.defaultPrevented) {
return;
}
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const { classList, scrollHeight, style } = this._element;
const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed
if (!isModalOverflowing) {
this._element.style.overflowY = 'hidden';
if (
(!isModalOverflowing && style.overflowY === 'hidden') ||
classList.contains(CLASS_NAME_STATIC)
) {
return;
}
this._element.classList.add(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
style.overflowY = 'hidden';
}
const modalTransitionDuration = getTransitionDurationFromElement(this._dialog);
EventHandler__default['default'].off(this._element, 'transitionend');
EventHandler__default['default'].one(this._element, 'transitionend', () => {
this._element.classList.remove(CLASS_NAME_STATIC);
classList.add(CLASS_NAME_STATIC);
this._queueCallback(() => {
classList.remove(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
EventHandler__default['default'].one(this._element, 'transitionend', () => {
this._element.style.overflowY = '';
});
emulateTransitionEnd(this._element, modalTransitionDuration);
this._queueCallback(() => {
style.overflowY = '';
}, this._dialog);
}
});
emulateTransitionEnd(this._element, modalTransitionDuration);
}, this._dialog);
this._element.focus();
} // ----------------------------------------------------------------------
@ -789,7 +969,9 @@
_adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getWidth();
const scrollbarWidth = this._scrollBar.getWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if (
@ -814,8 +996,7 @@
static jQueryInterface(config, relatedTarget) {
return this.each(function () {
const data =
Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
const data = Modal.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -835,7 +1016,7 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
@ -846,22 +1027,30 @@
event.preventDefault();
}
EventHandler__default['default'].one(target, EVENT_SHOW, (showEvent) => {
EventHandler__default.default.one(target, EVENT_SHOW, (showEvent) => {
if (showEvent.defaultPrevented) {
// only register focus restorer if modal will actually get shown
return;
}
EventHandler__default['default'].one(target, EVENT_HIDDEN, () => {
EventHandler__default.default.one(target, EVENT_HIDDEN, () => {
if (isVisible(this)) {
this.focus();
}
});
});
const data = Modal.getInstance(target) || new Modal(target);
}); // avoid conflict when clicking moddal toggler while another one is open
const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR);
if (allReadyOpen) {
Modal.getInstance(allReadyOpen).hide();
}
const data = Modal.getOrCreateInstance(target);
data.toggle(this);
}
);
enableDismissTrigger(Modal);
/**
* ------------------------------------------------------------------------
* jQuery

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap offcanvas.js v5.0.1 (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)
*/
@ -8,39 +8,38 @@
? (module.exports = factory(
require('./dom/selector-engine.js'),
require('./dom/manipulator.js'),
require('./dom/data.js'),
require('./dom/event-handler.js'),
require('./base-component.js')
))
: typeof define === 'function' && define.amd
? define([
'./dom/selector-engine',
'./dom/manipulator',
'./dom/data',
'./dom/event-handler',
'./base-component',
], factory)
? 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.Data,
global.EventHandler,
global.Base
)));
})(this, function (SelectorEngine, Manipulator, Data, EventHandler, BaseComponent) {
})(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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
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)
@ -120,22 +119,17 @@
return typeof obj.nodeType !== 'undefined';
};
const emulateTransitionEnd = (element, duration) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true;
element.removeEventListener(TRANSITION_END, listener);
const getElement = (obj) => {
if (isElement(obj)) {
// it's a jQuery object or a node element
return obj.jquery ? obj[0] : obj;
}
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
triggerTransitionEnd(element);
if (typeof obj === 'string' && obj.length > 0) {
return document.querySelector(obj);
}
}, emulatedDuration);
return null;
};
const typeCheckConfig = (componentName, config, configTypes) => {
@ -153,21 +147,11 @@
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
const isDisabled = (element) => {
@ -185,8 +169,19 @@
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 { jQuery } = window;
@ -198,9 +193,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -231,111 +235,173 @@
}
};
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);
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/scrollBar.js
* Bootstrap (v5.1.3): util/scrollBar.js
* 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 = () => {
class ScrollBarHelper {
constructor() {
this._element = document.body;
}
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
hide() {
const width = this.getWidth();
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
_setElementAttributes(
this._setElementAttributes(
this._element,
'paddingRight',
(calculatedValue) => calculatedValue + width
); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
this._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';
};
_disableOverFlow() {
this._saveInitialAttribute(this._element, 'overflow');
const _setElementAttributes = (selector, styleProp, callback) => {
const scrollbarWidth = getWidth();
SelectorEngine__default['default'].find(selector).forEach((element) => {
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
this._element.style.overflow = 'hidden';
}
_setElementAttributes(selector, styleProp, callback) {
const scrollbarWidth = this.getWidth();
const manipulationCallBack = (element) => {
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return;
}
const actualValue = element.style[styleProp];
this._saveInitialAttribute(element, 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');
this._applyManipulationCallback(selector, manipulationCallBack);
}
_resetElementAttributes('body', 'paddingRight');
reset() {
this._resetElementAttributes(this._element, 'overflow');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
this._resetElementAttributes(this._element, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
};
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine__default['default'].find(selector).forEach((element) => {
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
}
_saveInitialAttribute(element, styleProp) {
const actualValue = element.style[styleProp];
if (actualValue) {
Manipulator__default.default.setDataAttribute(element, styleProp, actualValue);
}
}
_resetElementAttributes(selector, styleProp) {
const manipulationCallBack = (element) => {
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;
}
});
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
_applyManipulationCallback(selector, callBack) {
if (isElement(selector)) {
callBack(selector);
} else {
SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
}
}
isOverflowing() {
return this.getWidth() > 0;
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): 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,
rootElement: document.body,
rootElement: 'body',
// 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',
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) {
@ -380,7 +446,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);
@ -393,9 +459,10 @@
}
_getConfig(config) {
config = { ...Default$1, ...(typeof config === 'object' ? config : {}) };
config.rootElement = config.rootElement || document.body;
typeCheckConfig(NAME$1, config, DefaultType$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$2, config, DefaultType$2);
return config;
}
@ -404,9 +471,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;
@ -417,31 +484,149 @@
return;
}
EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._element.remove();
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);
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): 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)
* --------------------------------------------------------------------------
*/
/**
@ -467,16 +652,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"]';
/**
* ------------------------------------------------------------------------
@ -484,12 +667,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
@ -511,7 +695,7 @@
return;
}
const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, {
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
relatedTarget,
});
@ -525,9 +709,7 @@
this._backdrop.show();
if (!this._config.scroll) {
hide();
this._enforceFocusOnElement(this._element);
new ScrollBarHelper().hide();
}
this._element.removeAttribute('aria-hidden');
@ -539,7 +721,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,
});
};
@ -552,13 +738,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();
@ -578,10 +764,10 @@
this._element.style.visibility = 'hidden';
if (!this._config.scroll) {
reset();
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);
@ -590,14 +776,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);
@ -606,6 +793,7 @@
_initializeBackDrop() {
return new Backdrop({
className: CLASS_NAME_BACKDROP,
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
@ -613,29 +801,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();
}
@ -644,9 +817,7 @@
static jQueryInterface(config) {
return this.each(function () {
const data =
Data__default['default'].get(this, DATA_KEY) ||
new Offcanvas(this, typeof config === 'object' ? config : {});
const data = Offcanvas.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -666,7 +837,7 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
@ -681,28 +852,29 @@
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();
}
const data = Data__default['default'].get(target, DATA_KEY) || new Offcanvas(target);
const data = Offcanvas.getOrCreateInstance(target);
data.toggle(this);
}
);
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine__default['default']
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () =>
SelectorEngine__default.default
.find(OPEN_SELECTOR)
.forEach((el) => (Data__default['default'].get(el, DATA_KEY) || new Offcanvas(el)).show());
});
.forEach((el) => Offcanvas.getOrCreateInstance(el).show())
);
enableDismissTrigger(Offcanvas);
/**
* ------------------------------------------------------------------------
* jQuery

File diff suppressed because one or more lines are too long

View File

@ -1,29 +1,29 @@
/*!
* Bootstrap popover.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap popover.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/selector-engine.js'),
require('./dom/data.js'),
require('./tooltip.js')
))
? (module.exports = factory(require('./tooltip.js')))
: typeof define === 'function' && define.amd
? define(['./dom/selector-engine', './dom/data', './tooltip'], factory)
? define(['./tooltip'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Popover = factory(global.SelectorEngine, global.Data, global.Tooltip)));
})(this, function (SelectorEngine, Data, Tooltip) {
(global.Popover = factory(global.Tooltip)));
})(this, function (Tooltip) {
'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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var Tooltip__default = /*#__PURE__*/ _interopDefaultLegacy(Tooltip);
const Tooltip__default = /*#__PURE__*/ _interopDefaultLegacy(Tooltip);
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const getjQuery = () => {
const { jQuery } = window;
@ -35,9 +35,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -64,7 +73,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): popover.js
* Bootstrap (v5.1.3): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -78,9 +87,8 @@
const DATA_KEY = 'bs.popover';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-popover';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const Default = {
...Tooltip__default['default'].Default,
...Tooltip__default.default.Default,
placement: 'right',
offset: [0, 8],
trigger: 'click',
@ -93,7 +101,7 @@
'</div>',
};
const DefaultType = {
...Tooltip__default['default'].DefaultType,
...Tooltip__default.default.DefaultType,
content: '(string|element|function)',
};
const Event = {
@ -108,8 +116,6 @@
MOUSEENTER: `mouseenter${EVENT_KEY}`,
MOUSELEAVE: `mouseleave${EVENT_KEY}`,
};
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const SELECTOR_TITLE = '.popover-header';
const SELECTOR_CONTENT = '.popover-body';
/**
@ -118,7 +124,7 @@
* ------------------------------------------------------------------------
*/
class Popover extends Tooltip__default['default'] {
class Popover extends Tooltip__default.default {
// Getters
static get Default() {
return Default;
@ -140,58 +146,23 @@
return this.getTitle() || this._getContent();
}
setContent() {
const tip = this.getTipElement(); // we use append for html objects to maintain js events
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);
this.setElementContent(
SelectorEngine__default['default'].findOne(SELECTOR_TITLE, tip),
this.getTitle()
);
let content = this._getContent();
if (typeof content === 'function') {
content = content.call(this._element);
}
this.setElementContent(
SelectorEngine__default['default'].findOne(SELECTOR_CONTENT, tip),
content
);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);
} // Private
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
}
_getContent() {
return this._element.getAttribute('data-bs-content') || this._config.content;
return this._resolvePossibleFunction(this._config.content);
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
} // Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY);
const _config = typeof config === 'object' ? config : null;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Popover(this, _config);
Data__default['default'].set(this, DATA_KEY, data);
}
const data = Popover.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

File diff suppressed because one or more lines are too long

View File

@ -1,51 +1,46 @@
/*!
* Bootstrap scrollspy.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap scrollspy.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/selector-engine.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/selector-engine',
'./dom/event-handler',
'./dom/manipulator',
'./base-component',
], factory)
? define(
['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.ScrollSpy = factory(
global.SelectorEngine,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (SelectorEngine, EventHandler, Manipulator, BaseComponent) {
})(this, function (EventHandler, Manipulator, SelectorEngine, 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 EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
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.0.1): util/index.js
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const MAX_UID = 1000000;
const toType = (obj) => {
if (obj === null || obj === undefined) {
return `${obj}`;
@ -56,19 +51,6 @@
.match(/\s([a-z]+)/i)[1]
.toLowerCase();
};
/**
* --------------------------------------------------------------------------
* Public Util Api
* --------------------------------------------------------------------------
*/
const getUID = (prefix) => {
do {
prefix += Math.floor(Math.random() * MAX_UID);
} while (document.getElementById(prefix));
return prefix;
};
const getSelector = (element) => {
let selector = element.getAttribute('data-bs-target');
@ -115,6 +97,19 @@
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];
@ -139,9 +134,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -168,7 +172,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): scrollspy.js
* Bootstrap (v5.1.3): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -202,6 +206,7 @@
const SELECTOR_NAV_LINKS = '.nav-link';
const SELECTOR_NAV_ITEMS = '.nav-item';
const SELECTOR_LIST_ITEMS = '.list-group-item';
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;
const SELECTOR_DROPDOWN = '.dropdown';
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
const METHOD_OFFSET = 'offset';
@ -212,17 +217,16 @@
* ------------------------------------------------------------------------
*/
class ScrollSpy extends BaseComponent__default['default'] {
class ScrollSpy extends BaseComponent__default.default {
constructor(element, config) {
super(element);
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
this._config = this._getConfig(config);
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`;
this._offsets = [];
this._targets = [];
this._activeTarget = null;
this._scrollHeight = 0;
EventHandler__default['default'].on(this._scrollElement, EVENT_SCROLL, () => this._process());
EventHandler__default.default.on(this._scrollElement, EVENT_SCROLL, () => this._process());
this.refresh();
this._process();
@ -244,12 +248,15 @@
this._offsets = [];
this._targets = [];
this._scrollHeight = this._getScrollHeight();
const targets = SelectorEngine__default['default'].find(this._selector);
const targets = SelectorEngine__default.default.find(
SELECTOR_LINK_ITEMS,
this._config.target
);
targets
.map((element) => {
const targetSelector = getSelectorFromElement(element);
const target = targetSelector
? SelectorEngine__default['default'].findOne(targetSelector)
? SelectorEngine__default.default.findOne(targetSelector)
: null;
if (target) {
@ -257,7 +264,7 @@
if (targetBCR.width || targetBCR.height) {
return [
Manipulator__default['default'][offsetMethod](target).top + offsetBase,
Manipulator__default.default[offsetMethod](target).top + offsetBase,
targetSelector,
];
}
@ -275,28 +282,17 @@
}
dispose() {
EventHandler__default['default'].off(this._scrollElement, EVENT_KEY);
EventHandler__default.default.off(this._scrollElement, EVENT_KEY);
super.dispose();
} // Private
_getConfig(config) {
config = {
...Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...Manipulator__default.default.getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {}),
};
if (typeof config.target !== 'string' && isElement(config.target)) {
let { id } = config.target;
if (!id) {
id = getUID(NAME);
config.target.id = id;
}
config.target = `#${id}`;
}
config.target = getElement(config.target) || document.documentElement;
typeCheckConfig(NAME, config, DefaultType);
return config;
}
@ -366,56 +362,51 @@
this._clear();
const queries = this._selector
.split(',')
.map((selector) => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`);
const link = SelectorEngine__default['default'].findOne(queries.join(','));
const queries = SELECTOR_LINK_ITEMS.split(',').map(
(selector) => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`
);
const link = SelectorEngine__default.default.findOne(queries.join(','), this._config.target);
link.classList.add(CLASS_NAME_ACTIVE);
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
SelectorEngine__default['default']
SelectorEngine__default.default
.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN))
.classList.add(CLASS_NAME_ACTIVE);
link.classList.add(CLASS_NAME_ACTIVE);
} else {
// Set triggered link as active
link.classList.add(CLASS_NAME_ACTIVE);
SelectorEngine__default['default']
SelectorEngine__default.default
.parents(link, SELECTOR_NAV_LIST_GROUP)
.forEach((listGroup) => {
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
SelectorEngine__default['default']
SelectorEngine__default.default
.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`)
.forEach((item) => item.classList.add(CLASS_NAME_ACTIVE)); // Handle special case when .nav-link is inside .nav-item
SelectorEngine__default['default']
SelectorEngine__default.default
.prev(listGroup, SELECTOR_NAV_ITEMS)
.forEach((navItem) => {
SelectorEngine__default['default']
SelectorEngine__default.default
.children(navItem, SELECTOR_NAV_LINKS)
.forEach((item) => item.classList.add(CLASS_NAME_ACTIVE));
});
});
}
EventHandler__default['default'].trigger(this._scrollElement, EVENT_ACTIVATE, {
EventHandler__default.default.trigger(this._scrollElement, EVENT_ACTIVATE, {
relatedTarget: target,
});
}
_clear() {
SelectorEngine__default['default']
.find(this._selector)
SelectorEngine__default.default
.find(SELECTOR_LINK_ITEMS, this._config.target)
.filter((node) => node.classList.contains(CLASS_NAME_ACTIVE))
.forEach((node) => node.classList.remove(CLASS_NAME_ACTIVE));
} // Static
static jQueryInterface(config) {
return this.each(function () {
const data =
ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
const data = ScrollSpy.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -435,8 +426,8 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine__default['default'].find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine__default.default.find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
});
/**
* ------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -1,36 +1,35 @@
/*!
* Bootstrap tab.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap tab.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/selector-engine.js'),
require('./dom/data.js'),
require('./dom/event-handler.js'),
require('./dom/selector-engine.js'),
require('./base-component.js')
))
: typeof define === 'function' && define.amd
? define([
'./dom/selector-engine',
'./dom/data',
'./dom/event-handler',
'./base-component',
], factory)
? define(['./dom/event-handler', './dom/selector-engine', './base-component'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Tab = factory(global.SelectorEngine, global.Data, global.EventHandler, global.Base)));
})(this, function (SelectorEngine, Data, EventHandler, BaseComponent) {
(global.Tab = factory(global.EventHandler, global.SelectorEngine, global.Base)));
})(this, function (EventHandler, SelectorEngine, 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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
const EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
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 getSelector = (element) => {
let selector = element.getAttribute('data-bs-target');
@ -75,8 +74,19 @@
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 { jQuery } = window;
@ -88,9 +98,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -117,7 +136,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tab.js
* Bootstrap (v5.1.3): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -154,7 +173,7 @@
* ------------------------------------------------------------------------
*/
class Tab extends BaseComponent__default['default'] {
class Tab extends BaseComponent__default.default {
// Getters
static get NAME() {
return NAME;
@ -179,16 +198,16 @@
listElement.nodeName === 'UL' || listElement.nodeName === 'OL'
? SELECTOR_ACTIVE_UL
: SELECTOR_ACTIVE;
previous = SelectorEngine__default['default'].find(itemSelector, listElement);
previous = SelectorEngine__default.default.find(itemSelector, listElement);
previous = previous[previous.length - 1];
}
const hideEvent = previous
? EventHandler__default['default'].trigger(previous, EVENT_HIDE, {
? EventHandler__default.default.trigger(previous, EVENT_HIDE, {
relatedTarget: this._element,
})
: null;
const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, {
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
relatedTarget: previous,
});
@ -199,10 +218,10 @@
this._activate(this._element, listElement);
const complete = () => {
EventHandler__default['default'].trigger(previous, EVENT_HIDDEN, {
EventHandler__default.default.trigger(previous, EVENT_HIDDEN, {
relatedTarget: this._element,
});
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, {
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
relatedTarget: previous,
});
};
@ -217,8 +236,8 @@
_activate(element, container, callback) {
const activeElements =
container && (container.nodeName === 'UL' || container.nodeName === 'OL')
? SelectorEngine__default['default'].find(SELECTOR_ACTIVE_UL, container)
: SelectorEngine__default['default'].children(container, SELECTOR_ACTIVE);
? SelectorEngine__default.default.find(SELECTOR_ACTIVE_UL, container)
: SelectorEngine__default.default.children(container, SELECTOR_ACTIVE);
const active = activeElements[0];
const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE);
@ -236,7 +255,7 @@
_transitionComplete(element, active, callback) {
if (active) {
active.classList.remove(CLASS_NAME_ACTIVE);
const dropdownChild = SelectorEngine__default['default'].findOne(
const dropdownChild = SelectorEngine__default.default.findOne(
SELECTOR_DROPDOWN_ACTIVE_CHILD,
active.parentNode
);
@ -272,7 +291,7 @@
const dropdownElement = element.closest(SELECTOR_DROPDOWN);
if (dropdownElement) {
SelectorEngine__default['default']
SelectorEngine__default.default
.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement)
.forEach((dropdown) => dropdown.classList.add(CLASS_NAME_ACTIVE));
}
@ -287,7 +306,7 @@
static jQueryInterface(config) {
return this.each(function () {
const data = Data__default['default'].get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -305,7 +324,7 @@
* ------------------------------------------------------------------------
*/
EventHandler__default['default'].on(
EventHandler__default.default.on(
document,
EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE,
@ -318,7 +337,7 @@
return;
}
const data = Data__default['default'].get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
data.show();
}
);

File diff suppressed because one or more lines are too long

View File

@ -1,36 +1,35 @@
/*!
* Bootstrap toast.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap toast.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('./base-component.js')
))
: typeof define === 'function' && define.amd
? define([
'./dom/data',
'./dom/event-handler',
'./dom/manipulator',
'./base-component',
], factory)
? define(['./dom/event-handler', './dom/manipulator', './base-component'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Toast = factory(global.Data, global.EventHandler, global.Manipulator, global.Base)));
})(this, function (Data, EventHandler, Manipulator, BaseComponent) {
(global.Toast = factory(global.EventHandler, global.Manipulator, global.Base)));
})(this, function (EventHandler, Manipulator, 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 Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
const EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
const Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
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) {
@ -43,6 +42,34 @@
.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 getElementFromSelector = (element) => {
const selector = getSelector(element);
return selector ? document.querySelector(selector) : null;
};
const isElement = (obj) => {
if (!obj || typeof obj !== 'object') {
return false;
@ -69,7 +96,34 @@
});
};
const reflow = (element) => element.offsetHeight;
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';
};
/**
* 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;
@ -81,9 +135,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -110,7 +173,38 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): toast.js
* 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): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -123,7 +217,6 @@
const NAME = 'toast';
const DATA_KEY = 'bs.toast';
const EVENT_KEY = `.${DATA_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
@ -133,7 +226,8 @@
const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_HIDE = 'hide';
const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_SHOWING = 'showing';
const DefaultType = {
@ -146,14 +240,13 @@
autohide: true,
delay: 5000,
};
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="toast"]';
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Toast extends BaseComponent__default['default'] {
class Toast extends BaseComponent__default.default {
constructor(element, config) {
super(element);
this._config = this._getConfig(config);
@ -177,7 +270,7 @@
} // Public
show() {
const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW);
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW);
if (showEvent.defaultPrevented) {
return;
@ -192,17 +285,17 @@
const complete = () => {
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN);
EventHandler__default.default.trigger(this._element, EVENT_SHOWN);
this._maybeScheduleHide();
};
this._element.classList.remove(CLASS_NAME_HIDE);
this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
reflow(this._element);
this._element.classList.add(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
@ -213,20 +306,24 @@
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;
}
const complete = () => {
this._element.classList.add(CLASS_NAME_HIDE);
this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
};
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.remove(CLASS_NAME_SHOW);
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
};
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
}
@ -243,7 +340,7 @@
_getConfig(config) {
config = {
...Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...Manipulator__default.default.getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {}),
};
typeCheckConfig(NAME, config, this.constructor.DefaultType);
@ -293,22 +390,16 @@
}
_setListeners() {
EventHandler__default['default'].on(
this._element,
EVENT_CLICK_DISMISS,
SELECTOR_DATA_DISMISS,
() => this.hide()
);
EventHandler__default['default'].on(this._element, EVENT_MOUSEOVER, (event) =>
EventHandler__default.default.on(this._element, EVENT_MOUSEOVER, (event) =>
this._onInteraction(event, true)
);
EventHandler__default['default'].on(this._element, EVENT_MOUSEOUT, (event) =>
EventHandler__default.default.on(this._element, EVENT_MOUSEOUT, (event) =>
this._onInteraction(event, false)
);
EventHandler__default['default'].on(this._element, EVENT_FOCUSIN, (event) =>
EventHandler__default.default.on(this._element, EVENT_FOCUSIN, (event) =>
this._onInteraction(event, true)
);
EventHandler__default['default'].on(this._element, EVENT_FOCUSOUT, (event) =>
EventHandler__default.default.on(this._element, EVENT_FOCUSOUT, (event) =>
this._onInteraction(event, false)
);
}
@ -320,13 +411,7 @@
static jQueryInterface(config) {
return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data) {
data = new Toast(this, _config);
}
const data = Toast.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -338,6 +423,8 @@
});
}
}
enableDismissTrigger(Toast);
/**
* ------------------------------------------------------------------------
* jQuery

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*!
* Bootstrap tooltip.js v5.0.1 (https://getbootstrap.com/)
* Bootstrap tooltip.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,44 +7,46 @@
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(
require('@popperjs/core'),
require('./dom/selector-engine.js'),
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([
? define(
[
'@popperjs/core',
'./dom/selector-engine',
'./dom/data',
'./dom/event-handler',
'./dom/manipulator',
'./dom/selector-engine',
'./base-component',
], factory)
],
factory
)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Tooltip = factory(
global.Popper,
global.SelectorEngine,
global.Data,
global.EventHandler,
global.Manipulator,
global.SelectorEngine,
global.Base
)));
})(this, function (Popper, SelectorEngine, Data, EventHandler, Manipulator, BaseComponent) {
})(this, function (Popper, Data, EventHandler, Manipulator, SelectorEngine, 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 };
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
const n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
for (const k in e) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(
n,
k,
@ -52,32 +54,29 @@
? d
: {
enumerable: true,
get: function () {
return e[k];
},
get: () => e[k],
}
);
}
});
}
n['default'] = e;
}
n.default = e;
return Object.freeze(n);
}
var Popper__namespace = /*#__PURE__*/ _interopNamespace(Popper);
var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine);
var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var BaseComponent__default = /*#__PURE__*/ _interopDefaultLegacy(BaseComponent);
const Popper__namespace = /*#__PURE__*/ _interopNamespace(Popper);
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.0.1): util/index.js
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const MAX_UID = 1000000;
const toType = (obj) => {
@ -123,7 +122,7 @@
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine__default['default'].findOne(obj);
return document.querySelector(obj);
}
return null;
@ -176,9 +175,18 @@
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -207,11 +215,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/sanitizer.js
* Bootstrap (v5.1.3): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const uriAttrs = new Set([
const uriAttributes = new Set([
'background',
'cite',
'href',
@ -225,35 +233,38 @@
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
/**
* A pattern that matches safe data URLs. Only matches image, video and audio types.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const DATA_URL_PATTERN =
/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const allowedAttribute = (attr, allowedAttributeList) => {
const attrName = attr.nodeName.toLowerCase();
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
if (allowedAttributeList.includes(attrName)) {
if (uriAttrs.has(attrName)) {
if (allowedAttributeList.includes(attributeName)) {
if (uriAttributes.has(attributeName)) {
return Boolean(
SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)
SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue)
);
}
return true;
}
const regExp = allowedAttributeList.filter((attrRegex) => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.
const regExp = allowedAttributeList.filter(
(attributeRegex) => attributeRegex instanceof RegExp
); // Check if a regular expression validates the attribute.
for (let i = 0, len = regExp.length; i < len; i++) {
if (regExp[i].test(attrName)) {
if (regExp[i].test(attributeName)) {
return true;
}
}
@ -305,23 +316,22 @@
const domParser = new window.DOMParser();
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
const allowlistKeys = Object.keys(allowList);
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
for (let i = 0, len = elements.length; i < len; i++) {
const el = elements[i];
const elName = el.nodeName.toLowerCase();
const element = elements[i];
const elementName = element.nodeName.toLowerCase();
if (!allowlistKeys.includes(elName)) {
el.parentNode.removeChild(el);
if (!Object.keys(allowList).includes(elementName)) {
element.remove();
continue;
}
const attributeList = [].concat(...el.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);
attributeList.forEach((attr) => {
if (!allowedAttribute(attr, allowedAttributes)) {
el.removeAttribute(attr.nodeName);
const attributeList = [].concat(...element.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
attributeList.forEach((attribute) => {
if (!allowedAttribute(attribute, allowedAttributes)) {
element.removeAttribute(attribute.nodeName);
}
});
}
@ -331,7 +341,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tooltip.js
* Bootstrap (v5.1.3): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -345,7 +355,6 @@
const DATA_KEY = 'bs.tooltip';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-tooltip';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
const DefaultType = {
animation: 'boolean',
@ -414,6 +423,8 @@
const HOVER_STATE_SHOW = 'show';
const HOVER_STATE_OUT = 'out';
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
const EVENT_MODAL_HIDE = 'hide.bs.modal';
const TRIGGER_HOVER = 'hover';
const TRIGGER_FOCUS = 'focus';
const TRIGGER_CLICK = 'click';
@ -424,7 +435,7 @@
* ------------------------------------------------------------------------
*/
class Tooltip extends BaseComponent__default['default'] {
class Tooltip extends BaseComponent__default.default {
constructor(element, config) {
if (typeof Popper__namespace === 'undefined') {
throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");
@ -500,19 +511,17 @@
dispose() {
clearTimeout(this._timeout);
EventHandler__default['default'].off(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
EventHandler__default.default.off(
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
if (this.tip && this.tip.parentNode) {
this.tip.parentNode.removeChild(this.tip);
if (this.tip) {
this.tip.remove();
}
if (this._popper) {
this._popper.destroy();
}
this._disposePopper();
super.dispose();
}
@ -526,7 +535,7 @@
return;
}
const showEvent = EventHandler__default['default'].trigger(
const showEvent = EventHandler__default.default.trigger(
this._element,
this.constructor.Event.SHOW
);
@ -538,6 +547,18 @@
if (showEvent.defaultPrevented || !isInTheDom) {
return;
} // A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title`
// This will be removed later in favor of a `setContent` method
if (
this.constructor.NAME === 'tooltip' &&
this.tip &&
this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML
) {
this._disposePopper();
this.tip.remove();
this.tip = null;
}
const tip = this.getTipElement();
@ -546,8 +567,6 @@
this._element.setAttribute('aria-describedby', tipId);
this.setContent();
if (this._config.animation) {
tip.classList.add(CLASS_NAME_FADE);
}
@ -562,11 +581,11 @@
this._addAttachmentClass(attachment);
const { container } = this._config;
Data__default['default'].set(tip, this.constructor.DATA_KEY, this);
Data__default.default.set(tip, this.constructor.DATA_KEY, this);
if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
container.appendChild(tip);
EventHandler__default['default'].trigger(this._element, this.constructor.Event.INSERTED);
container.append(tip);
EventHandler__default.default.trigger(this._element, this.constructor.Event.INSERTED);
}
if (this._popper) {
@ -580,10 +599,8 @@
}
tip.classList.add(CLASS_NAME_SHOW);
const customClass =
typeof this._config.customClass === 'function'
? this._config.customClass()
: this._config.customClass;
const customClass = this._resolvePossibleFunction(this._config.customClass);
if (customClass) {
tip.classList.add(...customClass.split(' '));
@ -594,14 +611,14 @@
if ('ontouchstart' in document.documentElement) {
[].concat(...document.body.children).forEach((element) => {
EventHandler__default['default'].on(element, 'mouseover', noop);
EventHandler__default.default.on(element, 'mouseover', noop);
});
}
const complete = () => {
const prevHoverState = this._hoverState;
this._hoverState = null;
EventHandler__default['default'].trigger(this._element, this.constructor.Event.SHOWN);
EventHandler__default.default.trigger(this._element, this.constructor.Event.SHOWN);
if (prevHoverState === HOVER_STATE_OUT) {
this._leave(null, this);
@ -625,24 +642,20 @@
return;
}
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip);
if (this._hoverState !== HOVER_STATE_SHOW) {
tip.remove();
}
this._cleanTipClass();
this._element.removeAttribute('aria-describedby');
EventHandler__default['default'].trigger(this._element, this.constructor.Event.HIDDEN);
EventHandler__default.default.trigger(this._element, this.constructor.Event.HIDDEN);
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
this._disposePopper();
};
const hideEvent = EventHandler__default['default'].trigger(
const hideEvent = EventHandler__default.default.trigger(
this._element,
this.constructor.Event.HIDE
);
@ -657,7 +670,7 @@
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((element) => EventHandler__default['default'].off(element, 'mouseover', noop));
.forEach((element) => EventHandler__default.default.off(element, 'mouseover', noop));
}
this._activeTrigger[TRIGGER_CLICK] = false;
@ -687,17 +700,26 @@
const element = document.createElement('div');
element.innerHTML = this._config.template;
this.tip = element.children[0];
const tip = element.children[0];
this.setContent(tip);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
this.tip = tip;
return this.tip;
}
setContent() {
const tip = this.getTipElement();
this.setElementContent(
SelectorEngine__default['default'].findOne(SELECTOR_TOOLTIP_INNER, tip),
this.getTitle()
);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);
}
_sanitizeAndSetContent(template, content, selector) {
const templateElement = SelectorEngine__default.default.findOne(selector, template);
if (!content && templateElement) {
templateElement.remove();
return;
} // we use append for html objects to maintain js events
this.setElementContent(templateElement, content);
}
setElementContent(element, content) {
@ -711,7 +733,7 @@
if (this._config.html) {
if (content.parentNode !== element) {
element.innerHTML = '';
element.appendChild(content);
element.append(content);
}
} else {
element.textContent = content.textContent;
@ -732,16 +754,9 @@
}
getTitle() {
let title = this._element.getAttribute('data-bs-original-title');
const title = this._element.getAttribute('data-bs-original-title') || this._config.title;
if (!title) {
title =
typeof this._config.title === 'function'
? this._config.title.call(this._element)
: this._config.title;
}
return title;
return this._resolvePossibleFunction(title);
}
updateAttachment(attachment) {
@ -757,15 +772,10 @@
} // Private
_initializeOnDelegatedTarget(event, context) {
const dataKey = this.constructor.DATA_KEY;
context = context || Data__default['default'].get(event.delegateTarget, dataKey);
if (!context) {
context = new this.constructor(event.delegateTarget, this._getDelegateConfig());
Data__default['default'].set(event.delegateTarget, dataKey, context);
}
return context;
return (
context ||
this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())
);
}
_getOffset() {
@ -782,6 +792,10 @@
return offset;
}
_resolvePossibleFunction(content) {
return typeof content === 'function' ? content.call(this._element) : content;
}
_getPopperConfig(attachment) {
const defaultBsPopperConfig = {
placement: attachment,
@ -832,7 +846,9 @@
}
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
this.getTipElement().classList.add(
`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`
);
}
_getAttachment(placement) {
@ -844,7 +860,7 @@
triggers.forEach((trigger) => {
if (trigger === 'click') {
EventHandler__default['default'].on(
EventHandler__default.default.on(
this._element,
this.constructor.Event.CLICK,
this._config.selector,
@ -859,13 +875,10 @@
trigger === TRIGGER_HOVER
? this.constructor.Event.MOUSELEAVE
: this.constructor.Event.FOCUSOUT;
EventHandler__default['default'].on(
this._element,
eventIn,
this._config.selector,
(event) => this._enter(event)
EventHandler__default.default.on(this._element, eventIn, this._config.selector, (event) =>
this._enter(event)
);
EventHandler__default['default'].on(
EventHandler__default.default.on(
this._element,
eventOut,
this._config.selector,
@ -880,9 +893,9 @@
}
};
EventHandler__default['default'].on(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
EventHandler__default.default.on(
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
@ -943,9 +956,8 @@
context = this._initializeOnDelegatedTarget(event, context);
if (event) {
context._activeTrigger[
event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = context._element.contains(event.relatedTarget);
context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =
context._element.contains(event.relatedTarget);
}
if (context._isWithActiveTrigger()) {
@ -978,7 +990,7 @@
}
_getConfig(config) {
const dataAttributes = Manipulator__default['default'].getDataAttributes(this._element);
const dataAttributes = Manipulator__default.default.getDataAttributes(this._element);
Object.keys(dataAttributes).forEach((dataAttr) => {
if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
delete dataAttributes[dataAttr];
@ -1018,26 +1030,31 @@
_getDelegateConfig() {
const config = {};
if (this._config) {
for (const key in this._config) {
if (this.constructor.Default[key] !== this._config[key]) {
config[key] = this._config[key];
}
}
}
} // In the future can be replaced with:
// const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
// `Object.fromEntries(keysWithDifferentValues)`
return config;
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g');
const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
}
_handlePopperPlacementChange(popperData) {
const { state } = popperData;
@ -1050,21 +1067,19 @@
this._cleanTipClass();
this._addAttachmentClass(this._getAttachment(state.placement));
}
_disposePopper() {
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
} // Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Tooltip(this, _config);
}
const data = Tooltip.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,14 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): alert.js
* Bootstrap (v5.1.3): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, getElementFromSelector } from './util/index';
import Data from './dom/data';
import { defineJQueryPlugin } from './util/index';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -19,15 +19,9 @@ import BaseComponent from './base-component';
const NAME = 'alert';
const DATA_KEY = 'bs.alert';
const EVENT_KEY = `.${DATA_KEY}`;
const DATA_API_KEY = '.data-api';
const SELECTOR_DISMISS = '[data-mdb-dismiss="alert"]';
const EVENT_CLOSE = `close${EVENT_KEY}`;
const EVENT_CLOSED = `closed${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_ALERT = 'alert';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
@ -46,67 +40,43 @@ class Alert extends BaseComponent {
// Public
close(element) {
const rootElement = element ? this._getRootElement(element) : this._element;
const customEvent = this._triggerCloseEvent(rootElement);
close() {
const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
if (customEvent === null || customEvent.defaultPrevented) {
if (closeEvent.defaultPrevented) {
return;
}
this._removeElement(rootElement);
this._element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
}
// Private
_getRootElement(element) {
return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`);
}
_triggerCloseEvent(element) {
return EventHandler.trigger(element, EVENT_CLOSE);
}
_removeElement(element) {
element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(element), element, isAnimated);
}
_destroyElement(element) {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
EventHandler.trigger(element, EVENT_CLOSED);
_destroyElement() {
this._element.remove();
EventHandler.trigger(this._element, EVENT_CLOSED);
this.dispose();
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const data = Alert.getOrCreateInstance(this);
if (!data) {
data = new Alert(this);
if (typeof config !== 'string') {
return;
}
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
throw new TypeError(`No method named "${config}"`);
}
if (config === 'close') {
data[config](this);
}
});
}
static handleDismiss(alertInstance) {
return function (event) {
if (event) {
event.preventDefault();
}
alertInstance.close(this);
};
}
}
/**
@ -115,7 +85,7 @@ class Alert extends BaseComponent {
* ------------------------------------------------------------------------
*/
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert()));
enableDismissTrigger(Alert, 'close');
/**
* ------------------------------------------------------------------------

View File

@ -1,17 +1,12 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): base-component.js
* Bootstrap (v5.1.3): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import Data from './dom/data';
import {
emulateTransitionEnd,
execute,
getElement,
getTransitionDurationFromElement,
} from './util/index';
import { executeAfterTransition, getElement } from './util/index';
import EventHandler from './dom/event-handler';
/**
@ -20,7 +15,7 @@ import EventHandler from './dom/event-handler';
* ------------------------------------------------------------------------
*/
const VERSION = '5.0.1';
const VERSION = '5.1.3';
class BaseComponent {
constructor(element) {
@ -44,21 +39,19 @@ class BaseComponent {
}
_queueCallback(callback, element, isAnimated = true) {
if (!isAnimated) {
execute(callback);
return;
}
const transitionDuration = getTransitionDurationFromElement(element);
EventHandler.one(element, 'transitionend', () => execute(callback));
emulateTransitionEnd(element, transitionDuration);
executeAfterTransition(callback, element, isAnimated);
}
/** Static */
static getInstance(element) {
return Data.get(element, this.DATA_KEY);
return Data.get(getElement(element), this.DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
static get VERSION() {

View File

@ -1,12 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): button.js
* Bootstrap (v5.1.3): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
@ -51,11 +50,7 @@ class Button extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
if (!data) {
data = new Button(this);
}
const data = Button.getOrCreateInstance(this);
if (config === 'toggle') {
data[config]();
@ -74,11 +69,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, (event) =>
event.preventDefault();
const button = event.target.closest(SELECTOR_DATA_TOGGLE);
let data = Data.get(button, DATA_KEY);
if (!data) {
data = new Button(button);
}
const data = Button.getOrCreateInstance(button);
data.toggle();
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): carousel.js
* Bootstrap (v5.1.3): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -10,11 +10,11 @@ import {
getElementFromSelector,
isRTL,
isVisible,
getNextActiveElement,
reflow,
triggerTransitionEnd,
typeCheckConfig,
} from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
@ -59,6 +59,11 @@ const ORDER_PREV = 'prev';
const DIRECTION_LEFT = 'left';
const DIRECTION_RIGHT = 'right';
const KEY_TO_DIRECTION = {
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
[ARROW_RIGHT_KEY]: DIRECTION_LEFT,
};
const EVENT_SLIDE = `slide${EVENT_KEY}`;
const EVENT_SLID = `slid${EVENT_KEY}`;
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
@ -135,10 +140,8 @@ class Carousel extends BaseComponent {
// Public
next() {
if (!this._isSliding) {
this._slide(ORDER_NEXT);
}
}
nextWhenVisible() {
// Don't call next when the page isn't visible
@ -149,10 +152,8 @@ class Carousel extends BaseComponent {
}
prev() {
if (!this._isSliding) {
this._slide(ORDER_PREV);
}
}
pause(event) {
if (!event) {
@ -217,7 +218,8 @@ class Carousel extends BaseComponent {
_getConfig(config) {
config = {
...Default,
...config,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
@ -257,11 +259,15 @@ class Carousel extends BaseComponent {
}
_addTouchEventListeners() {
const start = (event) => {
if (
const hasPointerPenTouch = (event) => {
return (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
);
};
const start = (event) => {
if (hasPointerPenTouch(event)) {
this.touchStartX = event.clientX;
} else if (!this._pointerEvent) {
this.touchStartX = event.touches[0].clientX;
@ -275,10 +281,7 @@ class Carousel extends BaseComponent {
};
const end = (event) => {
if (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
if (hasPointerPenTouch(event)) {
this.touchDeltaX = event.clientX - this.touchStartX;
}
@ -305,7 +308,7 @@ class Carousel extends BaseComponent {
};
SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach((itemImg) => {
EventHandler.on(itemImg, EVENT_DRAG_START, (e) => e.preventDefault());
EventHandler.on(itemImg, EVENT_DRAG_START, (event) => event.preventDefault());
});
if (this._pointerEvent) {
@ -325,12 +328,10 @@ class Carousel extends BaseComponent {
return;
}
if (event.key === ARROW_LEFT_KEY) {
const direction = KEY_TO_DIRECTION[event.key];
if (direction) {
event.preventDefault();
this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault();
this._slide(DIRECTION_LEFT);
this._slide(direction);
}
}
@ -343,20 +344,7 @@ class Carousel extends BaseComponent {
_getItemByOrder(order, activeElement) {
const isNext = order === ORDER_NEXT;
const isPrev = order === ORDER_PREV;
const activeIndex = this._getItemIndex(activeElement);
const lastItemIndex = this._items.length - 1;
const isGoingToWrap =
(isPrev && activeIndex === 0) || (isNext && activeIndex === lastItemIndex);
if (isGoingToWrap && !this._config.wrap) {
return activeElement;
}
const delta = isPrev ? -1 : 1;
const itemIndex = (activeIndex + delta) % this._items.length;
return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);
}
_triggerSlideEvent(relatedTarget, eventDirectionName) {
@ -432,6 +420,10 @@ class Carousel extends BaseComponent {
return;
}
if (this._isSliding) {
return;
}
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
if (slideEvent.defaultPrevented) {
return;
@ -520,12 +512,9 @@ class Carousel extends BaseComponent {
// Static
static carouselInterface(element, config) {
let data = Data.get(element, DATA_KEY);
let _config = {
...Default,
...Manipulator.getDataAttributes(element),
};
const data = Carousel.getOrCreateInstance(element, config);
let { _config } = data;
if (typeof config === 'object') {
_config = {
..._config,
@ -535,10 +524,6 @@ class Carousel extends BaseComponent {
const action = typeof config === 'string' ? config : _config.slide;
if (!data) {
data = new Carousel(element, _config);
}
if (typeof config === 'number') {
data.to(config);
} else if (typeof action === 'string') {
@ -579,7 +564,7 @@ class Carousel extends BaseComponent {
Carousel.carouselInterface(target, config);
if (slideIndex) {
Data.get(target, DATA_KEY).to(slideIndex);
Carousel.getInstance(target).to(slideIndex);
}
event.preventDefault();
@ -598,7 +583,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
for (let i = 0, len = carousels.length; i < len; i++) {
Carousel.carouselInterface(carousels[i], Data.get(carousels[i], DATA_KEY));
Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));
}
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): collapse.js
* Bootstrap (v5.1.3): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -32,12 +32,12 @@ const DATA_API_KEY = '.data-api';
const Default = {
toggle: true,
parent: '',
parent: null,
};
const DefaultType = {
toggle: 'boolean',
parent: '(string|element)',
parent: '(null|element)',
};
const EVENT_SHOW = `show${EVENT_KEY}`;
@ -50,11 +50,13 @@ 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 = '.show, .collapsing';
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="collapse"]';
/**
@ -69,10 +71,7 @@ class Collapse extends BaseComponent {
this._isTransitioning = false;
this._config = this._getConfig(config);
this._triggerArray = SelectorEngine.find(
`${SELECTOR_DATA_TOGGLE}[href="#${this._element.id}"],` +
`${SELECTOR_DATA_TOGGLE}[data-mdb-target="#${this._element.id}"]`
);
this._triggerArray = [];
const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
@ -89,10 +88,10 @@ class Collapse extends BaseComponent {
}
}
this._parent = this._config.parent ? this._getParent() : null;
this._initializeChildren();
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray);
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
}
if (this._config.toggle) {
@ -113,7 +112,7 @@ class Collapse extends BaseComponent {
// Public
toggle() {
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isShown()) {
this.hide();
} else {
this.show();
@ -121,31 +120,24 @@ class Collapse extends BaseComponent {
}
show() {
if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || this._isShown()) {
return;
}
let actives;
let actives = [];
let activesData;
if (this._parent) {
actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent).filter((elem) => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-mdb-parent') === this._config.parent;
}
return elem.classList.contains(CLASS_NAME_COLLAPSE);
});
if (actives.length === 0) {
actives = null;
}
if (this._config.parent) {
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(
(elem) => !children.includes(elem)
); // remove children if greater depth
}
const container = SelectorEngine.findOne(this._selector);
if (actives) {
if (actives.length) {
const tempActiveData = actives.find((elem) => container !== elem);
activesData = tempActiveData ? Data.get(tempActiveData, DATA_KEY) : null;
activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;
if (activesData && activesData._isTransitioning) {
return;
@ -157,17 +149,15 @@ class Collapse extends BaseComponent {
return;
}
if (actives) {
actives.forEach((elemActive) => {
if (container !== elemActive) {
Collapse.collapseInterface(elemActive, 'hide');
Collapse.getOrCreateInstance(elemActive, { toggle: false }).hide();
}
if (!activesData) {
Data.set(elemActive, DATA_KEY, null);
}
});
}
const dimension = this._getDimension();
@ -176,22 +166,17 @@ class Collapse extends BaseComponent {
this._element.style[dimension] = 0;
if (this._triggerArray.length) {
this._triggerArray.forEach((element) => {
element.classList.remove(CLASS_NAME_COLLAPSED);
element.setAttribute('aria-expanded', true);
});
}
this._addAriaAndCollapsedClass(this._triggerArray, true);
this._isTransitioning = true;
this.setTransitioning(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] = '';
this.setTransitioning(false);
EventHandler.trigger(this._element, EVENT_SHOWN);
};
@ -203,7 +188,7 @@ class Collapse extends BaseComponent {
}
hide() {
if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || !this._isShown()) {
return;
}
@ -222,22 +207,19 @@ class Collapse extends BaseComponent {
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
const triggerArrayLength = this._triggerArray.length;
if (triggerArrayLength > 0) {
for (let i = 0; i < triggerArrayLength; i++) {
const trigger = this._triggerArray[i];
const elem = getElementFromSelector(trigger);
if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
trigger.classList.add(CLASS_NAME_COLLAPSED);
trigger.setAttribute('aria-expanded', false);
}
if (elem && !this._isShown(elem)) {
this._addAriaAndCollapsedClass([trigger], false);
}
}
this.setTransitioning(true);
this._isTransitioning = true;
const complete = () => {
this.setTransitioning(false);
this._isTransitioning = false;
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE);
EventHandler.trigger(this._element, EVENT_HIDDEN);
@ -248,8 +230,8 @@ class Collapse extends BaseComponent {
this._queueCallback(complete, this._element, true);
}
setTransitioning(isTransitioning) {
this._isTransitioning = isTransitioning;
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
}
// Private
@ -257,39 +239,40 @@ class Collapse extends BaseComponent {
_getConfig(config) {
config = {
...Default,
...Manipulator.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(WIDTH) ? WIDTH : HEIGHT;
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
}
_getParent() {
let { parent } = this._config;
parent = getElement(parent);
const selector = `${SELECTOR_DATA_TOGGLE}[data-mdb-parent="${parent}"]`;
SelectorEngine.find(selector, parent).forEach((element) => {
const selected = getElementFromSelector(element);
this._addAriaAndCollapsedClass(selected, [element]);
});
return parent;
}
_addAriaAndCollapsedClass(element, triggerArray) {
if (!element || !triggerArray.length) {
_initializeChildren() {
if (!this._config.parent) {
return;
}
const isOpen = element.classList.contains(CLASS_NAME_SHOW);
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
SelectorEngine.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) {
@ -304,21 +287,14 @@ class Collapse extends BaseComponent {
// Static
static collapseInterface(element, config) {
let data = Data.get(element, DATA_KEY);
const _config = {
...Default,
...Manipulator.getDataAttributes(element),
...(typeof config === 'object' && config ? config : {}),
};
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
static jQueryInterface(config) {
return this.each(function () {
const _config = {};
if (typeof config === 'string' && /show|hide/.test(config)) {
_config.toggle = false;
}
if (!data) {
data = new Collapse(element, _config);
}
const data = Collapse.getOrCreateInstance(this, _config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -327,11 +303,6 @@ class Collapse extends BaseComponent {
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Collapse.collapseInterface(this, config);
});
}
}
@ -351,26 +322,11 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
event.preventDefault();
}
const triggerData = Manipulator.getDataAttributes(this);
const selector = getSelectorFromElement(this);
const selectorElements = SelectorEngine.find(selector);
selectorElements.forEach((element) => {
const data = Data.get(element, DATA_KEY);
let config;
if (data) {
// update parent attribute
if (data._parent === null && typeof triggerData.parent === 'string') {
data._config.parent = triggerData.parent;
data._parent = data._getParent();
}
config = 'toggle';
} else {
config = triggerData;
}
Collapse.collapseInterface(element, config);
Collapse.getOrCreateInstance(element, { toggle: false }).toggle();
});
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/data.js
* Bootstrap (v5.1.3): dom/data.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/event-handler.js
* Bootstrap (v5.1.3): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -113,7 +113,6 @@ function bootstrapDelegationHandler(element, selector, fn) {
event.delegateTarget = target;
if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, selector, fn);
}

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/manipulator.js
* Bootstrap (v5.1.3): dom/manipulator.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -64,8 +64,8 @@ const Manipulator = {
const rect = element.getBoundingClientRect();
return {
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft,
top: rect.top + window.pageYOffset,
left: rect.left + window.pageXOffset,
};
},

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/selector-engine.js
* Bootstrap (v5.1.3): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -11,6 +11,8 @@
* ------------------------------------------------------------------------
*/
import { isDisabled, isVisible } from '../util/index';
const NODE_TEXT = 3;
const SelectorEngine = {
@ -69,6 +71,23 @@ const SelectorEngine = {
return [];
},
focusableChildren(element) {
const focusables = [
'a',
'button',
'input',
'textarea',
'select',
'details',
'[tabindex]',
'[contenteditable="true"]',
]
.map((selector) => `${selector}:not([tabindex^="-"])`)
.join(', ');
return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el));
},
};
export default SelectorEngine;

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dropdown.js
* Bootstrap (v5.1.3): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -11,14 +11,14 @@ import {
defineJQueryPlugin,
getElement,
getElementFromSelector,
getNextActiveElement,
isDisabled,
isElement,
isVisible,
isRTL,
isVisible,
noop,
typeCheckConfig,
} from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
@ -48,7 +48,6 @@ const EVENT_HIDE = `hide${EVENT_KEY}`;
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const EVENT_CLICK = `click${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
@ -103,8 +102,6 @@ class Dropdown extends BaseComponent {
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._inNavbar = this._detectNavbar();
this._addEventListeners();
}
// Getters
@ -124,26 +121,14 @@ class Dropdown extends BaseComponent {
// Public
toggle() {
if (isDisabled(this._element)) {
return;
}
const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
if (isActive) {
this.hide();
return;
}
this.show();
return this._isShown() ? this.hide() : this.show();
}
show() {
if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || this._isShown(this._menu)) {
return;
}
const parent = Dropdown.getParentFromElement(this._element);
const relatedTarget = {
relatedTarget: this._element,
};
@ -154,34 +139,12 @@ class Dropdown extends BaseComponent {
return;
}
const parent = Dropdown.getParentFromElement(this._element);
// Totally disable Popper for Dropdowns in Navbar
if (this._inNavbar) {
Manipulator.setDataAttribute(this._menu, 'popper', 'none');
} else {
if (typeof Popper === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator.setDataAttribute(this._menu, 'popper', 'static');
}
this._createPopper(parent);
}
// If this is a touch-enabled device we add extra
@ -197,13 +160,13 @@ class Dropdown extends BaseComponent {
this._element.focus();
this._element.setAttribute('aria-expanded', true);
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
this._menu.classList.add(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget);
}
hide() {
if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || !this._isShown(this._menu)) {
return;
}
@ -231,13 +194,6 @@ class Dropdown extends BaseComponent {
// Private
_addEventListeners() {
EventHandler.on(this._element, EVENT_CLICK, (event) => {
event.preventDefault();
this.toggle();
});
}
_completeHide(relatedTarget) {
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget);
if (hideEvent.defaultPrevented) {
@ -286,6 +242,37 @@ class Dropdown extends BaseComponent {
return config;
}
_createPopper(parent) {
if (typeof Popper === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator.setDataAttribute(this._menu, 'popper', 'static');
}
}
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
}
_getMenuElement() {
return SelectorEngine.next(this._element, SELECTOR_MENU)[0];
}
@ -366,53 +353,33 @@ class Dropdown extends BaseComponent {
};
}
_selectMenuItem(event) {
_selectMenuItem({ key, target }) {
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);
if (!items.length) {
return;
}
let index = items.indexOf(event.target);
// Up
if (event.key === ARROW_UP_KEY && index > 0) {
index--;
}
// Down
if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
index++;
}
// index is -1 if the first keydown is an ArrowUp
index = index === -1 ? 0 : index;
items[index].focus();
// if target isn't included in items (e.g. when expanding the dropdown)
// allow cycling to get the last item in case key equals ARROW_UP_KEY
getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
}
// Static
static dropdownInterface(element, config) {
let data = Data.get(element, DATA_KEY);
const _config = typeof config === 'object' ? config : null;
static jQueryInterface(config) {
return this.each(function () {
const data = Dropdown.getOrCreateInstance(this, config);
if (!data) {
data = new Dropdown(element, _config);
if (typeof config !== 'string') {
return;
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`);
}
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Dropdown.dropdownInterface(this, config);
});
}
@ -427,12 +394,12 @@ class Dropdown extends BaseComponent {
const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data.get(toggles[i], DATA_KEY);
const context = Dropdown.getInstance(toggles[i]);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
if (!context._isShown()) {
continue;
}
@ -505,28 +472,28 @@ class Dropdown extends BaseComponent {
return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE)
? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
const instance = Dropdown.getOrCreateInstance(getToggleButton);
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus();
instance.hide();
return;
}
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
getToggleButton().click();
if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
if (!isActive) {
instance.show();
}
instance._selectMenuItem(event);
return;
}
if (!isActive || event.key === SPACE_KEY) {
Dropdown.clearMenus();
return;
}
Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
}
}
@ -547,7 +514,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault();
Dropdown.dropdownInterface(this);
Dropdown.getOrCreateInstance(this).toggle();
});
/**

View File

@ -1,15 +1,13 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): modal.js
* Bootstrap (v5.1.3): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import {
defineJQueryPlugin,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
isRTL,
isVisible,
reflow,
@ -18,13 +16,11 @@ import {
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
import {
getWidth as getScrollBarWidth,
hide as scrollBarHide,
reset as scrollBarReset,
} from './util/scrollbar';
import ScrollBarHelper from './util/scrollbar';
import BaseComponent from './base-component';
import Backdrop from './util/backdrop';
import FocusTrap from './util/focustrap';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -55,7 +51,6 @@ 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}`;
@ -68,10 +63,10 @@ const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_STATIC = 'modal-static';
const OPEN_SELECTOR = '.modal.show';
const SELECTOR_DIALOG = '.modal-dialog';
const SELECTOR_MODAL_BODY = '.modal-body';
const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="modal"]';
const SELECTOR_DATA_DISMISS = '[data-mdb-dismiss="modal"]';
/**
* ------------------------------------------------------------------------
@ -86,9 +81,11 @@ class Modal extends BaseComponent {
this._config = this._getConfig(config);
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
this._backdrop = this._initializeBackDrop();
this._focustrap = this._initializeFocusTrap();
this._isShown = false;
this._ignoreBackdropClick = false;
this._isTransitioning = false;
this._scrollBar = new ScrollBarHelper();
}
// Getters
@ -112,21 +109,21 @@ class Modal extends BaseComponent {
return;
}
if (this._isAnimated()) {
this._isTransitioning = true;
}
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget,
});
if (this._isShown || showEvent.defaultPrevented) {
if (showEvent.defaultPrevented) {
return;
}
this._isShown = true;
scrollBarHide();
if (this._isAnimated()) {
this._isTransitioning = true;
}
this._scrollBar.hide();
document.body.classList.add(CLASS_NAME_OPEN);
@ -135,10 +132,6 @@ class Modal extends BaseComponent {
this._setEscapeEvent();
this._setResizeEvent();
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, (event) =>
this.hide(event)
);
EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, (event) => {
if (event.target === this._element) {
@ -150,11 +143,7 @@ class Modal extends BaseComponent {
this._showBackdrop(() => this._showElement(relatedTarget));
}
hide(event) {
if (event) {
event.preventDefault();
}
hide() {
if (!this._isShown || this._isTransitioning) {
return;
}
@ -175,7 +164,7 @@ class Modal extends BaseComponent {
this._setEscapeEvent();
this._setResizeEvent();
EventHandler.off(document, EVENT_FOCUSIN);
this._focustrap.deactivate();
this._element.classList.remove(CLASS_NAME_SHOW);
@ -189,14 +178,8 @@ class Modal extends BaseComponent {
[window, this._dialog].forEach((htmlElement) => EventHandler.off(htmlElement, EVENT_KEY));
this._backdrop.dispose();
this._focustrap.deactivate();
super.dispose();
/**
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
* Do not move `document` in `htmlElements` array
* It will remove `EVENT_CLICK_DATA_API` event that should remain
*/
EventHandler.off(document, EVENT_FOCUSIN);
}
handleUpdate() {
@ -212,11 +195,17 @@ class Modal extends BaseComponent {
});
}
_initializeFocusTrap() {
return new FocusTrap({
trapElement: this._element,
});
}
_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...config,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
@ -228,7 +217,7 @@ class Modal extends BaseComponent {
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
// Don't move modal's DOM position
document.body.appendChild(this._element);
document.body.append(this._element);
}
this._element.style.display = 'block';
@ -247,13 +236,9 @@ class Modal extends BaseComponent {
this._element.classList.add(CLASS_NAME_SHOW);
if (this._config.focus) {
this._enforceFocus();
}
const transitionComplete = () => {
if (this._config.focus) {
this._element.focus();
this._focustrap.activate();
}
this._isTransitioning = false;
@ -265,19 +250,6 @@ class Modal extends BaseComponent {
this._queueCallback(transitionComplete, this._dialog, isAnimated);
}
_enforceFocus() {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => {
if (
document !== event.target &&
this._element !== event.target &&
!this._element.contains(event.target)
) {
this._element.focus();
}
});
}
_setEscapeEvent() {
if (this._isShown) {
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
@ -310,7 +282,7 @@ class Modal extends BaseComponent {
this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN);
this._resetAdjustments();
scrollBarReset();
this._scrollBar.reset();
EventHandler.trigger(this._element, EVENT_HIDDEN);
});
}
@ -346,25 +318,31 @@ class Modal extends BaseComponent {
return;
}
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const { classList, scrollHeight, style } = this._element;
const isModalOverflowing = scrollHeight > document.documentElement.clientHeight;
if (!isModalOverflowing) {
this._element.style.overflowY = 'hidden';
// return if the following background transition hasn't yet completed
if (
(!isModalOverflowing && style.overflowY === 'hidden') ||
classList.contains(CLASS_NAME_STATIC)
) {
return;
}
this._element.classList.add(CLASS_NAME_STATIC);
const modalTransitionDuration = getTransitionDurationFromElement(this._dialog);
EventHandler.off(this._element, 'transitionend');
EventHandler.one(this._element, 'transitionend', () => {
this._element.classList.remove(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
EventHandler.one(this._element, 'transitionend', () => {
this._element.style.overflowY = '';
});
emulateTransitionEnd(this._element, modalTransitionDuration);
style.overflowY = 'hidden';
}
});
emulateTransitionEnd(this._element, modalTransitionDuration);
classList.add(CLASS_NAME_STATIC);
this._queueCallback(() => {
classList.remove(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
this._queueCallback(() => {
style.overflowY = '';
}, this._dialog);
}
}, this._dialog);
this._element.focus();
}
@ -374,7 +352,7 @@ class Modal extends BaseComponent {
_adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getScrollBarWidth();
const scrollbarWidth = this._scrollBar.getWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if (
@ -401,8 +379,7 @@ class Modal extends BaseComponent {
static jQueryInterface(config, relatedTarget) {
return this.each(function () {
const data =
Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
const data = Modal.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -443,11 +420,19 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
});
});
const data = Modal.getInstance(target) || new Modal(target);
// avoid conflict when clicking moddal toggler while another one is open
const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
if (allReadyOpen) {
Modal.getInstance(allReadyOpen).hide();
}
const data = Modal.getOrCreateInstance(target);
data.toggle(this);
});
enableDismissTrigger(Modal);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,7 +1,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Bootstrap (v5.1.3): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -12,13 +12,14 @@ import {
isVisible,
typeCheckConfig,
} from './util/index';
import { hide as scrollBarHide, reset as scrollBarReset } from './util/scrollbar';
import Data from './dom/data';
import ScrollBarHelper from './util/scrollbar';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
import SelectorEngine from './dom/selector-engine';
import Manipulator from './dom/manipulator';
import Backdrop from './util/backdrop';
import FocusTrap from './util/focustrap';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -46,18 +47,16 @@ const DefaultType = {
};
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-mdb-dismiss="offcanvas"]';
const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="offcanvas"]';
/**
@ -73,6 +72,7 @@ class Offcanvas extends BaseComponent {
this._config = this._getConfig(config);
this._isShown = false;
this._backdrop = this._initializeBackDrop();
this._focustrap = this._initializeFocusTrap();
this._addEventListeners();
}
@ -109,8 +109,7 @@ class Offcanvas extends BaseComponent {
this._backdrop.show();
if (!this._config.scroll) {
scrollBarHide();
this._enforceFocusOnElement(this._element);
new ScrollBarHelper().hide();
}
this._element.removeAttribute('aria-hidden');
@ -119,6 +118,10 @@ class Offcanvas extends BaseComponent {
this._element.classList.add(CLASS_NAME_SHOW);
const completeCallBack = () => {
if (!this._config.scroll) {
this._focustrap.activate();
}
EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget });
};
@ -136,7 +139,7 @@ class Offcanvas extends BaseComponent {
return;
}
EventHandler.off(document, EVENT_FOCUSIN);
this._focustrap.deactivate();
this._element.blur();
this._isShown = false;
this._element.classList.remove(CLASS_NAME_SHOW);
@ -149,7 +152,7 @@ class Offcanvas extends BaseComponent {
this._element.style.visibility = 'hidden';
if (!this._config.scroll) {
scrollBarReset();
new ScrollBarHelper().reset();
}
EventHandler.trigger(this._element, EVENT_HIDDEN);
@ -160,8 +163,8 @@ class Offcanvas extends BaseComponent {
dispose() {
this._backdrop.dispose();
this._focustrap.deactivate();
super.dispose();
EventHandler.off(document, EVENT_FOCUSIN);
}
// Private
@ -178,6 +181,7 @@ class Offcanvas extends BaseComponent {
_initializeBackDrop() {
return new Backdrop({
className: CLASS_NAME_BACKDROP,
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
@ -185,23 +189,13 @@ class Offcanvas extends BaseComponent {
});
}
_enforceFocusOnElement(element) {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.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.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.key === ESCAPE_KEY) {
this.hide();
@ -213,8 +207,7 @@ class Offcanvas extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data =
Data.get(this, DATA_KEY) || new Offcanvas(this, typeof config === 'object' ? config : {});
const data = Offcanvas.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -259,17 +252,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
Offcanvas.getInstance(allReadyOpen).hide();
}
const data = Data.get(target, DATA_KEY) || new Offcanvas(target);
const data = Offcanvas.getOrCreateInstance(target);
data.toggle(this);
});
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine.find(OPEN_SELECTOR).forEach((el) =>
(Data.get(el, DATA_KEY) || new Offcanvas(el)).show()
);
});
EventHandler.on(window, EVENT_LOAD_DATA_API, () =>
SelectorEngine.find(OPEN_SELECTOR).forEach((el) => Offcanvas.getOrCreateInstance(el).show())
);
enableDismissTrigger(Offcanvas);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,13 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): popover.js
* Bootstrap (v5.1.3): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin } from './util/index';
import Data from './dom/data';
import SelectorEngine from './dom/selector-engine';
import Tooltip from './tooltip';
/**
@ -20,7 +18,6 @@ const NAME = 'popover';
const DATA_KEY = 'bs.popover';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-popover';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const Default = {
...Tooltip.Default,
@ -54,9 +51,6 @@ const Event = {
MOUSELEAVE: `mouseleave${EVENT_KEY}`,
};
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const SELECTOR_TITLE = '.popover-header';
const SELECTOR_CONTENT = '.popover-body';
@ -91,54 +85,26 @@ class Popover extends Tooltip {
return this.getTitle() || this._getContent();
}
setContent() {
const tip = this.getTipElement();
// we use append for html objects to maintain js events
this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle());
let content = this._getContent();
if (typeof content === 'function') {
content = content.call(this._element);
}
this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);
this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);
}
// Private
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
}
_getContent() {
return this._element.getAttribute('data-mdb-content') || this._config.content;
return this._resolvePossibleFunction(this._config.content);
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' ? config : null;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Popover(this, _config);
Data.set(this, DATA_KEY, data);
}
const data = Popover.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

View File

@ -1,15 +1,14 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): scrollspy.js
* Bootstrap (v5.1.3): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import {
defineJQueryPlugin,
getElement,
getSelectorFromElement,
getUID,
isElement,
typeCheckConfig,
} from './util/index';
import EventHandler from './dom/event-handler';
@ -52,6 +51,7 @@ const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
const SELECTOR_NAV_LINKS = '.nav-link';
const SELECTOR_NAV_ITEMS = '.nav-item';
const SELECTOR_LIST_ITEMS = '.list-group-item';
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;
const SELECTOR_DROPDOWN = '.dropdown';
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
@ -67,14 +67,11 @@ const METHOD_POSITION = 'position';
class ScrollSpy extends BaseComponent {
constructor(element, config) {
super(element);
if (!getSelectorFromElement(element)) {
return;
}
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
this._config = this._getConfig(config);
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`;
this._offsets = [];
this._targets = [];
this._activeTarget = null;
@ -110,7 +107,7 @@ class ScrollSpy extends BaseComponent {
this._targets = [];
this._scrollHeight = this._getScrollHeight();
const targets = SelectorEngine.find(this._selector);
const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);
targets
.map((element) => {
@ -148,15 +145,7 @@ class ScrollSpy extends BaseComponent {
...(typeof config === 'object' && config ? config : {}),
};
if (typeof config.target !== 'string' && isElement(config.target)) {
let { id } = config.target;
if (!id) {
id = getUID(NAME);
config.target.id = id;
}
config.target = `#${id}`;
}
config.target = getElement(config.target) || document.documentElement;
typeCheckConfig(NAME, config, DefaultType);
@ -224,23 +213,19 @@ class ScrollSpy extends BaseComponent {
this._clear();
const queries = this._selector
.split(',')
.map((selector) => `${selector}[data-mdb-target="${target}"],${selector}[href="${target}"]`);
const queries = SELECTOR_LINK_ITEMS.split(',').map(
(selector) => `${selector}[data-mdb-target="${target}"],${selector}[href="${target}"]`
);
const link = SelectorEngine.findOne(queries.join(','));
const link = SelectorEngine.findOne(queries.join(','), this._config.target);
link.classList.add(CLASS_NAME_ACTIVE);
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
SelectorEngine.findOne(
SELECTOR_DROPDOWN_TOGGLE,
link.closest(SELECTOR_DROPDOWN)
).classList.add(CLASS_NAME_ACTIVE);
link.classList.add(CLASS_NAME_ACTIVE);
} else {
// Set triggered link as active
link.classList.add(CLASS_NAME_ACTIVE);
SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP).forEach((listGroup) => {
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
@ -263,7 +248,7 @@ class ScrollSpy extends BaseComponent {
}
_clear() {
SelectorEngine.find(this._selector)
SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
.filter((node) => node.classList.contains(CLASS_NAME_ACTIVE))
.forEach((node) => node.classList.remove(CLASS_NAME_ACTIVE));
}
@ -272,9 +257,7 @@ class ScrollSpy extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data =
ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
const data = ScrollSpy.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -296,8 +279,9 @@ class ScrollSpy extends BaseComponent {
*/
// EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
// SelectorEngine.find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
// });
// SelectorEngine.find(SELECTOR_DATA_SPY)
// .forEach(spy => new ScrollSpy(spy))
// })
/**
* ------------------------------------------------------------------------

View File

@ -1,12 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tab.js
* Bootstrap (v5.1.3): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, getElementFromSelector, isDisabled, reflow } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import SelectorEngine from './dom/selector-engine';
import BaseComponent from './base-component';
@ -187,7 +186,7 @@ class Tab extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data = Data.get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -215,7 +214,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
return;
}
const data = Data.get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
data.show();
});

View File

@ -1,15 +1,15 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): toast.js
* Bootstrap (v5.1.3): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, reflow, typeCheckConfig } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import BaseComponent from './base-component';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -21,7 +21,6 @@ const NAME = 'toast';
const DATA_KEY = 'bs.toast';
const EVENT_KEY = `.${DATA_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
@ -32,7 +31,7 @@ const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_HIDE = 'hide';
const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_SHOWING = 'showing';
@ -48,8 +47,6 @@ const Default = {
delay: 5000,
};
const SELECTOR_DATA_DISMISS = '[data-mdb-dismiss="toast"]';
/**
* ------------------------------------------------------------------------
* Class Definition
@ -98,15 +95,14 @@ class Toast extends BaseComponent {
const complete = () => {
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_SHOWN);
this._maybeScheduleHide();
};
this._element.classList.remove(CLASS_NAME_HIDE);
this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
reflow(this._element);
this._element.classList.add(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
@ -124,11 +120,13 @@ class Toast extends BaseComponent {
}
const complete = () => {
this._element.classList.add(CLASS_NAME_HIDE);
this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.remove(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_HIDDEN);
};
this._element.classList.remove(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
}
@ -198,7 +196,6 @@ class Toast extends BaseComponent {
}
_setListeners() {
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(this._element, EVENT_MOUSEOVER, (event) => this._onInteraction(event, true));
EventHandler.on(this._element, EVENT_MOUSEOUT, (event) => this._onInteraction(event, false));
EventHandler.on(this._element, EVENT_FOCUSIN, (event) => this._onInteraction(event, true));
@ -214,12 +211,7 @@ class Toast extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data) {
data = new Toast(this, _config);
}
const data = Toast.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -232,6 +224,8 @@ class Toast extends BaseComponent {
}
}
enableDismissTrigger(Toast);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tooltip.js
* Bootstrap (v5.1.3): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -34,7 +34,6 @@ const NAME = 'tooltip';
const DATA_KEY = 'bs.tooltip';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-tooltip';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
const DefaultType = {
@ -110,6 +109,9 @@ const HOVER_STATE_SHOW = 'show';
const HOVER_STATE_OUT = 'out';
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
const EVENT_MODAL_HIDE = 'hide.bs.modal';
const TRIGGER_HOVER = 'hover';
const TRIGGER_FOCUS = 'focus';
@ -205,19 +207,16 @@ class Tooltip extends BaseComponent {
clearTimeout(this._timeout);
EventHandler.off(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
if (this.tip && this.tip.parentNode) {
this.tip.parentNode.removeChild(this.tip);
}
if (this._popper) {
this._popper.destroy();
if (this.tip) {
this.tip.remove();
}
this._disposePopper();
super.dispose();
}
@ -241,14 +240,24 @@ class Tooltip extends BaseComponent {
return;
}
// A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-mdb-original-title`
// This will be removed later in favor of a `setContent` method
if (
this.constructor.NAME === 'tooltip' &&
this.tip &&
this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML
) {
this._disposePopper();
this.tip.remove();
this.tip = null;
}
const tip = this.getTipElement();
const tipId = getUID(this.constructor.NAME);
tip.setAttribute('id', tipId);
this._element.setAttribute('aria-describedby', tipId);
this.setContent();
if (this._config.animation) {
tip.classList.add(CLASS_NAME_FADE);
}
@ -265,7 +274,7 @@ class Tooltip extends BaseComponent {
Data.set(tip, this.constructor.DATA_KEY, this);
if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
container.appendChild(tip);
container.append(tip);
EventHandler.trigger(this._element, this.constructor.Event.INSERTED);
}
@ -277,10 +286,7 @@ class Tooltip extends BaseComponent {
tip.classList.add(CLASS_NAME_SHOW);
const customClass =
typeof this._config.customClass === 'function'
? this._config.customClass()
: this._config.customClass;
const customClass = this._resolvePossibleFunction(this._config.customClass);
if (customClass) {
tip.classList.add(...customClass.split(' '));
}
@ -321,18 +327,15 @@ class Tooltip extends BaseComponent {
return;
}
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip);
if (this._hoverState !== HOVER_STATE_SHOW) {
tip.remove();
}
this._cleanTipClass();
this._element.removeAttribute('aria-describedby');
EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
this._disposePopper();
};
const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);
@ -379,14 +382,28 @@ class Tooltip extends BaseComponent {
const element = document.createElement('div');
element.innerHTML = this._config.template;
this.tip = element.children[0];
const tip = element.children[0];
this.setContent(tip);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
this.tip = tip;
return this.tip;
}
setContent() {
const tip = this.getTipElement();
this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle());
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);
}
_sanitizeAndSetContent(template, content, selector) {
const templateElement = SelectorEngine.findOne(selector, template);
if (!content && templateElement) {
templateElement.remove();
return;
}
// we use append for html objects to maintain js events
this.setElementContent(templateElement, content);
}
setElementContent(element, content) {
@ -401,7 +418,7 @@ class Tooltip extends BaseComponent {
if (this._config.html) {
if (content.parentNode !== element) {
element.innerHTML = '';
element.appendChild(content);
element.append(content);
}
} else {
element.textContent = content.textContent;
@ -422,16 +439,9 @@ class Tooltip extends BaseComponent {
}
getTitle() {
let title = this._element.getAttribute('data-mdb-original-title');
const title = this._element.getAttribute('data-mdb-original-title') || this._config.title;
if (!title) {
title =
typeof this._config.title === 'function'
? this._config.title.call(this._element)
: this._config.title;
}
return title;
return this._resolvePossibleFunction(title);
}
updateAttachment(attachment) {
@ -449,15 +459,10 @@ class Tooltip extends BaseComponent {
// Private
_initializeOnDelegatedTarget(event, context) {
const dataKey = this.constructor.DATA_KEY;
context = context || Data.get(event.delegateTarget, dataKey);
if (!context) {
context = new this.constructor(event.delegateTarget, this._getDelegateConfig());
Data.set(event.delegateTarget, dataKey, context);
}
return context;
return (
context ||
this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())
);
}
_getOffset() {
@ -474,6 +479,10 @@ class Tooltip extends BaseComponent {
return offset;
}
_resolvePossibleFunction(content) {
return typeof content === 'function' ? content.call(this._element) : content;
}
_getPopperConfig(attachment) {
const defaultBsPopperConfig = {
placement: attachment,
@ -525,7 +534,9 @@ class Tooltip extends BaseComponent {
}
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
this.getTipElement().classList.add(
`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`
);
}
_getAttachment(placement) {
@ -569,8 +580,8 @@ class Tooltip extends BaseComponent {
};
EventHandler.on(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
@ -634,9 +645,8 @@ class Tooltip extends BaseComponent {
context = this._initializeOnDelegatedTarget(event, context);
if (event) {
context._activeTrigger[
event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = context._element.contains(event.relatedTarget);
context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =
context._element.contains(event.relatedTarget);
}
if (context._isWithActiveTrigger()) {
@ -713,25 +723,31 @@ class Tooltip extends BaseComponent {
_getDelegateConfig() {
const config = {};
if (this._config) {
for (const key in this._config) {
if (this.constructor.Default[key] !== this._config[key]) {
config[key] = this._config[key];
}
}
}
// In the future can be replaced with:
// const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
// `Object.fromEntries(keysWithDifferentValues)`
return config;
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g');
const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
}
_handlePopperPlacementChange(popperData) {
const { state } = popperData;
@ -744,20 +760,18 @@ class Tooltip extends BaseComponent {
this._addAttachmentClass(this._getAttachment(state.placement));
}
_disposePopper() {
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Tooltip(this, _config);
}
const data = Tooltip.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

View File

@ -1,34 +1,29 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): 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)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import {
emulateTransitionEnd,
execute,
getTransitionDurationFromElement,
reflow,
typeCheckConfig,
} from './index';
import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index';
const Default = {
className: 'modal-backdrop',
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
rootElement: 'body', // give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType = {
className: 'string',
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
rootElement: '(element|string)',
clickCallback: '(function|null)',
};
const NAME = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
@ -79,7 +74,7 @@ class Backdrop {
_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);
}
@ -96,7 +91,8 @@ class Backdrop {
...(typeof config === 'object' ? config : {}),
};
config.rootElement = config.rootElement || document.body;
// use getElement() with the default "body" to get a fresh Element on each instantiation
config.rootElement = getElement(config.rootElement);
typeCheckConfig(NAME, config, DefaultType);
return config;
}
@ -106,7 +102,7 @@ class Backdrop {
return;
}
this._config.rootElement.appendChild(this._getElement());
this._config.rootElement.append(this._getElement());
EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
@ -122,19 +118,12 @@ class Backdrop {
EventHandler.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._element.remove();
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler.one(this._getElement(), 'transitionend', () => execute(callback));
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
}
}

View File

@ -0,0 +1,32 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/component-functions.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import { getElementFromSelector, isDisabled } from './index';
const enableDismissTrigger = (component, method = 'hide') => {
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
const name = component.NAME;
EventHandler.on(document, clickEvent, `[data-mdb-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]();
});
};
export { enableDismissTrigger };

View File

@ -0,0 +1,105 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/focustrap.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import SelectorEngine from '../dom/selector-engine';
import { typeCheckConfig } from './index';
const Default = {
trapElement: null, // The element to trap focus inside of
autofocus: true,
};
const DefaultType = {
trapElement: 'element',
autofocus: 'boolean',
};
const NAME = 'focustrap';
const DATA_KEY = 'bs.focustrap';
const EVENT_KEY = `.${DATA_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`;
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.off(document, EVENT_KEY); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => this._handleFocusin(event));
EventHandler.on(document, EVENT_KEYDOWN_TAB, (event) => this._handleKeydown(event));
this._isActive = true;
}
deactivate() {
if (!this._isActive) {
return;
}
this._isActive = false;
EventHandler.off(document, EVENT_KEY);
}
// Private
_handleFocusin(event) {
const { target } = event;
const { trapElement } = this._config;
if (target === document || target === trapElement || trapElement.contains(target)) {
return;
}
const elements = SelectorEngine.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,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
}
}
export default FocusTrap;

View File

@ -1,8 +1,6 @@
import SelectorEngine from '../dom/selector-engine';
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/index.js
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -127,30 +125,12 @@ const getElement = (obj) => {
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine.findOne(obj);
return document.querySelector(obj);
}
return null;
};
const emulateTransitionEnd = (element, duration) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true;
element.removeEventListener(TRANSITION_END, listener);
}
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
triggerTransitionEnd(element);
}
}, emulatedDuration);
};
const typeCheckConfig = (componentName, config, configTypes) => {
Object.keys(configTypes).forEach((property) => {
const expectedTypes = configTypes[property];
@ -166,22 +146,11 @@ const typeCheckConfig = (componentName, config, configTypes) => {
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
const isDisabled = (element) => {
@ -225,7 +194,18 @@ const findShadowRoot = (element) => {
const noop = () => {};
const reflow = (element) => element.offsetHeight;
/**
* 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;
@ -237,9 +217,18 @@ const getjQuery = () => {
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -270,6 +259,63 @@ const execute = (callback) => {
}
};
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);
};
/**
* Return the previous/next element of a list.
*
* @param {array} list The list of elements
* @param activeElement The active element
* @param shouldGetNext Choose to get next or previous element
* @param isCycleAllowed
* @return {Element|elem} The proper element
*/
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
let index = list.indexOf(activeElement);
// if the element does not exist in the list return an element depending on the direction and if cycle is allowed
if (index === -1) {
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
}
const listLength = list.length;
index += shouldGetNext ? 1 : -1;
if (isCycleAllowed) {
index = (index + listLength) % listLength;
}
return list[Math.max(0, Math.min(index, listLength - 1))];
};
export {
getElement,
getUID,
@ -278,16 +324,17 @@ export {
getTransitionDurationFromElement,
triggerTransitionEnd,
isElement,
emulateTransitionEnd,
typeCheckConfig,
isVisible,
isDisabled,
findShadowRoot,
noop,
getNextActiveElement,
reflow,
getjQuery,
onDOMContentLoaded,
isRTL,
defineJQueryPlugin,
execute,
executeAfterTransition,
};

View File

@ -1,11 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/sanitizer.js
* Bootstrap (v5.1.3): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const uriAttrs = new Set([
const uriAttributes = new Set([
'background',
'cite',
'href',
@ -21,35 +21,36 @@ const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
/**
* A pattern that matches safe data URLs. Only matches image, video and audio types.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const DATA_URL_PATTERN =
/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const allowedAttribute = (attr, allowedAttributeList) => {
const attrName = attr.nodeName.toLowerCase();
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
if (allowedAttributeList.includes(attrName)) {
if (uriAttrs.has(attrName)) {
if (allowedAttributeList.includes(attributeName)) {
if (uriAttributes.has(attributeName)) {
return Boolean(
SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)
SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue)
);
}
return true;
}
const regExp = allowedAttributeList.filter((attrRegex) => attrRegex instanceof RegExp);
const regExp = allowedAttributeList.filter((attributeRegex) => attributeRegex instanceof RegExp);
// Check if a regular expression validates the attribute.
for (let i = 0, len = regExp.length; i < len; i++) {
if (regExp[i].test(attrName)) {
if (regExp[i].test(attributeName)) {
return true;
}
}
@ -102,25 +103,24 @@ export function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
const domParser = new window.DOMParser();
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
const allowlistKeys = Object.keys(allowList);
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
for (let i = 0, len = elements.length; i < len; i++) {
const el = elements[i];
const elName = el.nodeName.toLowerCase();
const element = elements[i];
const elementName = element.nodeName.toLowerCase();
if (!allowlistKeys.includes(elName)) {
el.parentNode.removeChild(el);
if (!Object.keys(allowList).includes(elementName)) {
element.remove();
continue;
}
const attributeList = [].concat(...el.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);
const attributeList = [].concat(...element.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
attributeList.forEach((attr) => {
if (!allowedAttribute(attr, allowedAttributes)) {
el.removeAttribute(attr.nodeName);
attributeList.forEach((attribute) => {
if (!allowedAttribute(attribute, allowedAttributes)) {
element.removeAttribute(attribute.nodeName);
}
});
}

View File

@ -1,71 +1,86 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/scrollBar.js
* Bootstrap (v5.1.3): util/scrollBar.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import SelectorEngine from '../dom/selector-engine';
import Manipulator from '../dom/manipulator';
import { isElement } from './index';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => {
class ScrollBarHelper {
constructor() {
this._element = document.body;
}
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(
hide() {
const width = this.getWidth();
this._disableOverFlow();
// give padding to element to balance the hidden scrollbar width
this._setElementAttributes(
this._element,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
this._setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - width
);
};
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
};
_disableOverFlow() {
this._saveInitialAttribute(this._element, 'overflow');
this._element.style.overflow = 'hidden';
}
const _setElementAttributes = (selector, styleProp, callback) => {
const scrollbarWidth = getWidth();
SelectorEngine.find(selector).forEach((element) => {
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
_setElementAttributes(selector, styleProp, callback) {
const scrollbarWidth = this.getWidth();
const manipulationCallBack = (element) => {
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return;
}
const actualValue = element.style[styleProp];
this._saveInitialAttribute(element, styleProp);
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.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');
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach((element) => {
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) {
Manipulator.setDataAttribute(element, styleProp, actualValue);
}
}
_resetElementAttributes(selector, styleProp) {
const manipulationCallBack = (element) => {
const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp);
@ -73,11 +88,22 @@ const _resetElementAttributes = (selector, styleProp) => {
Manipulator.removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
};
};
const isBodyOverflowing = () => {
return getWidth() > 0;
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
export { getWidth, hide, isBodyOverflowing, reset };
_applyManipulationCallback(selector, callBack) {
if (isElement(selector)) {
callBack(selector);
} else {
SelectorEngine.find(selector, this._element).forEach(callBack);
}
}
isOverflowing() {
return this.getWidth() > 0;
}
}
export default ScrollBarHelper;

View File

@ -1,14 +1,14 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): alert.js
* Bootstrap (v5.1.3): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, getElementFromSelector } from './util/index';
import Data from './dom/data';
import { defineJQueryPlugin } from './util/index';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -19,15 +19,9 @@ import BaseComponent from './base-component';
const NAME = 'alert';
const DATA_KEY = 'bs.alert';
const EVENT_KEY = `.${DATA_KEY}`;
const DATA_API_KEY = '.data-api';
const SELECTOR_DISMISS = '[data-bs-dismiss="alert"]';
const EVENT_CLOSE = `close${EVENT_KEY}`;
const EVENT_CLOSED = `closed${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_ALERT = 'alert';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
@ -46,67 +40,43 @@ class Alert extends BaseComponent {
// Public
close(element) {
const rootElement = element ? this._getRootElement(element) : this._element;
const customEvent = this._triggerCloseEvent(rootElement);
close() {
const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
if (customEvent === null || customEvent.defaultPrevented) {
if (closeEvent.defaultPrevented) {
return;
}
this._removeElement(rootElement);
this._element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
}
// Private
_getRootElement(element) {
return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`);
}
_triggerCloseEvent(element) {
return EventHandler.trigger(element, EVENT_CLOSE);
}
_removeElement(element) {
element.classList.remove(CLASS_NAME_SHOW);
const isAnimated = element.classList.contains(CLASS_NAME_FADE);
this._queueCallback(() => this._destroyElement(element), element, isAnimated);
}
_destroyElement(element) {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
EventHandler.trigger(element, EVENT_CLOSED);
_destroyElement() {
this._element.remove();
EventHandler.trigger(this._element, EVENT_CLOSED);
this.dispose();
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const data = Alert.getOrCreateInstance(this);
if (!data) {
data = new Alert(this);
if (typeof config !== 'string') {
return;
}
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
throw new TypeError(`No method named "${config}"`);
}
if (config === 'close') {
data[config](this);
}
});
}
static handleDismiss(alertInstance) {
return function (event) {
if (event) {
event.preventDefault();
}
alertInstance.close(this);
};
}
}
/**
@ -115,7 +85,7 @@ class Alert extends BaseComponent {
* ------------------------------------------------------------------------
*/
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert()));
enableDismissTrigger(Alert, 'close');
/**
* ------------------------------------------------------------------------

View File

@ -1,17 +1,12 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): base-component.js
* Bootstrap (v5.1.3): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import Data from './dom/data';
import {
emulateTransitionEnd,
execute,
getElement,
getTransitionDurationFromElement,
} from './util/index';
import { executeAfterTransition, getElement } from './util/index';
import EventHandler from './dom/event-handler';
/**
@ -20,7 +15,7 @@ import EventHandler from './dom/event-handler';
* ------------------------------------------------------------------------
*/
const VERSION = '5.0.1';
const VERSION = '5.1.3';
class BaseComponent {
constructor(element) {
@ -44,21 +39,19 @@ class BaseComponent {
}
_queueCallback(callback, element, isAnimated = true) {
if (!isAnimated) {
execute(callback);
return;
}
const transitionDuration = getTransitionDurationFromElement(element);
EventHandler.one(element, 'transitionend', () => execute(callback));
emulateTransitionEnd(element, transitionDuration);
executeAfterTransition(callback, element, isAnimated);
}
/** Static */
static getInstance(element) {
return Data.get(element, this.DATA_KEY);
return Data.get(getElement(element), this.DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
static get VERSION() {

View File

@ -1,12 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): button.js
* Bootstrap (v5.1.3): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
@ -51,11 +50,7 @@ class Button extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
if (!data) {
data = new Button(this);
}
const data = Button.getOrCreateInstance(this);
if (config === 'toggle') {
data[config]();
@ -74,11 +69,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, (event) =>
event.preventDefault();
const button = event.target.closest(SELECTOR_DATA_TOGGLE);
let data = Data.get(button, DATA_KEY);
if (!data) {
data = new Button(button);
}
const data = Button.getOrCreateInstance(button);
data.toggle();
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): carousel.js
* Bootstrap (v5.1.3): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -10,11 +10,11 @@ import {
getElementFromSelector,
isRTL,
isVisible,
getNextActiveElement,
reflow,
triggerTransitionEnd,
typeCheckConfig,
} from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
@ -59,6 +59,11 @@ const ORDER_PREV = 'prev';
const DIRECTION_LEFT = 'left';
const DIRECTION_RIGHT = 'right';
const KEY_TO_DIRECTION = {
[ARROW_LEFT_KEY]: DIRECTION_RIGHT,
[ARROW_RIGHT_KEY]: DIRECTION_LEFT,
};
const EVENT_SLIDE = `slide${EVENT_KEY}`;
const EVENT_SLID = `slid${EVENT_KEY}`;
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`;
@ -135,10 +140,8 @@ class Carousel extends BaseComponent {
// Public
next() {
if (!this._isSliding) {
this._slide(ORDER_NEXT);
}
}
nextWhenVisible() {
// Don't call next when the page isn't visible
@ -149,10 +152,8 @@ class Carousel extends BaseComponent {
}
prev() {
if (!this._isSliding) {
this._slide(ORDER_PREV);
}
}
pause(event) {
if (!event) {
@ -217,7 +218,8 @@ class Carousel extends BaseComponent {
_getConfig(config) {
config = {
...Default,
...config,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
@ -257,11 +259,15 @@ class Carousel extends BaseComponent {
}
_addTouchEventListeners() {
const start = (event) => {
if (
const hasPointerPenTouch = (event) => {
return (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
);
};
const start = (event) => {
if (hasPointerPenTouch(event)) {
this.touchStartX = event.clientX;
} else if (!this._pointerEvent) {
this.touchStartX = event.touches[0].clientX;
@ -275,10 +281,7 @@ class Carousel extends BaseComponent {
};
const end = (event) => {
if (
this._pointerEvent &&
(event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)
) {
if (hasPointerPenTouch(event)) {
this.touchDeltaX = event.clientX - this.touchStartX;
}
@ -305,7 +308,7 @@ class Carousel extends BaseComponent {
};
SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach((itemImg) => {
EventHandler.on(itemImg, EVENT_DRAG_START, (e) => e.preventDefault());
EventHandler.on(itemImg, EVENT_DRAG_START, (event) => event.preventDefault());
});
if (this._pointerEvent) {
@ -325,12 +328,10 @@ class Carousel extends BaseComponent {
return;
}
if (event.key === ARROW_LEFT_KEY) {
const direction = KEY_TO_DIRECTION[event.key];
if (direction) {
event.preventDefault();
this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault();
this._slide(DIRECTION_LEFT);
this._slide(direction);
}
}
@ -343,20 +344,7 @@ class Carousel extends BaseComponent {
_getItemByOrder(order, activeElement) {
const isNext = order === ORDER_NEXT;
const isPrev = order === ORDER_PREV;
const activeIndex = this._getItemIndex(activeElement);
const lastItemIndex = this._items.length - 1;
const isGoingToWrap =
(isPrev && activeIndex === 0) || (isNext && activeIndex === lastItemIndex);
if (isGoingToWrap && !this._config.wrap) {
return activeElement;
}
const delta = isPrev ? -1 : 1;
const itemIndex = (activeIndex + delta) % this._items.length;
return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
return getNextActiveElement(this._items, activeElement, isNext, this._config.wrap);
}
_triggerSlideEvent(relatedTarget, eventDirectionName) {
@ -432,6 +420,10 @@ class Carousel extends BaseComponent {
return;
}
if (this._isSliding) {
return;
}
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
if (slideEvent.defaultPrevented) {
return;
@ -520,12 +512,9 @@ class Carousel extends BaseComponent {
// Static
static carouselInterface(element, config) {
let data = Data.get(element, DATA_KEY);
let _config = {
...Default,
...Manipulator.getDataAttributes(element),
};
const data = Carousel.getOrCreateInstance(element, config);
let { _config } = data;
if (typeof config === 'object') {
_config = {
..._config,
@ -535,10 +524,6 @@ class Carousel extends BaseComponent {
const action = typeof config === 'string' ? config : _config.slide;
if (!data) {
data = new Carousel(element, _config);
}
if (typeof config === 'number') {
data.to(config);
} else if (typeof action === 'string') {
@ -579,7 +564,7 @@ class Carousel extends BaseComponent {
Carousel.carouselInterface(target, config);
if (slideIndex) {
Data.get(target, DATA_KEY).to(slideIndex);
Carousel.getInstance(target).to(slideIndex);
}
event.preventDefault();
@ -598,7 +583,7 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
for (let i = 0, len = carousels.length; i < len; i++) {
Carousel.carouselInterface(carousels[i], Data.get(carousels[i], DATA_KEY));
Carousel.carouselInterface(carousels[i], Carousel.getInstance(carousels[i]));
}
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): collapse.js
* Bootstrap (v5.1.3): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -32,12 +32,12 @@ const DATA_API_KEY = '.data-api';
const Default = {
toggle: true,
parent: '',
parent: null,
};
const DefaultType = {
toggle: 'boolean',
parent: '(string|element)',
parent: '(null|element)',
};
const EVENT_SHOW = `show${EVENT_KEY}`;
@ -50,11 +50,13 @@ 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 = '.show, .collapsing';
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="collapse"]';
/**
@ -69,10 +71,7 @@ class Collapse extends BaseComponent {
this._isTransitioning = false;
this._config = this._getConfig(config);
this._triggerArray = SelectorEngine.find(
`${SELECTOR_DATA_TOGGLE}[href="#${this._element.id}"],` +
`${SELECTOR_DATA_TOGGLE}[data-bs-target="#${this._element.id}"]`
);
this._triggerArray = [];
const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
@ -89,10 +88,10 @@ class Collapse extends BaseComponent {
}
}
this._parent = this._config.parent ? this._getParent() : null;
this._initializeChildren();
if (!this._config.parent) {
this._addAriaAndCollapsedClass(this._element, this._triggerArray);
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
}
if (this._config.toggle) {
@ -113,7 +112,7 @@ class Collapse extends BaseComponent {
// Public
toggle() {
if (this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isShown()) {
this.hide();
} else {
this.show();
@ -121,31 +120,24 @@ class Collapse extends BaseComponent {
}
show() {
if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || this._isShown()) {
return;
}
let actives;
let actives = [];
let activesData;
if (this._parent) {
actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent).filter((elem) => {
if (typeof this._config.parent === 'string') {
return elem.getAttribute('data-bs-parent') === this._config.parent;
}
return elem.classList.contains(CLASS_NAME_COLLAPSE);
});
if (actives.length === 0) {
actives = null;
}
if (this._config.parent) {
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
actives = SelectorEngine.find(SELECTOR_ACTIVES, this._config.parent).filter(
(elem) => !children.includes(elem)
); // remove children if greater depth
}
const container = SelectorEngine.findOne(this._selector);
if (actives) {
if (actives.length) {
const tempActiveData = actives.find((elem) => container !== elem);
activesData = tempActiveData ? Data.get(tempActiveData, DATA_KEY) : null;
activesData = tempActiveData ? Collapse.getInstance(tempActiveData) : null;
if (activesData && activesData._isTransitioning) {
return;
@ -157,17 +149,15 @@ class Collapse extends BaseComponent {
return;
}
if (actives) {
actives.forEach((elemActive) => {
if (container !== elemActive) {
Collapse.collapseInterface(elemActive, 'hide');
Collapse.getOrCreateInstance(elemActive, { toggle: false }).hide();
}
if (!activesData) {
Data.set(elemActive, DATA_KEY, null);
}
});
}
const dimension = this._getDimension();
@ -176,23 +166,17 @@ class Collapse extends BaseComponent {
this._element.style[dimension] = 0;
if (this._triggerArray.length) {
this._triggerArray.forEach((element) => {
element.classList.remove(CLASS_NAME_COLLAPSED);
element.setAttribute('aria-expanded', true);
});
}
this.setTransitioning(true);
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] = '';
this.setTransitioning(false);
EventHandler.trigger(this._element, EVENT_SHOWN);
};
@ -204,7 +188,7 @@ class Collapse extends BaseComponent {
}
hide() {
if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) {
if (this._isTransitioning || !this._isShown()) {
return;
}
@ -223,22 +207,19 @@ class Collapse extends BaseComponent {
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW);
const triggerArrayLength = this._triggerArray.length;
if (triggerArrayLength > 0) {
for (let i = 0; i < triggerArrayLength; i++) {
const trigger = this._triggerArray[i];
const elem = getElementFromSelector(trigger);
if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) {
trigger.classList.add(CLASS_NAME_COLLAPSED);
trigger.setAttribute('aria-expanded', false);
}
if (elem && !this._isShown(elem)) {
this._addAriaAndCollapsedClass([trigger], false);
}
}
this.setTransitioning(true);
this._isTransitioning = true;
const complete = () => {
this.setTransitioning(false);
this._isTransitioning = false;
this._element.classList.remove(CLASS_NAME_COLLAPSING);
this._element.classList.add(CLASS_NAME_COLLAPSE);
EventHandler.trigger(this._element, EVENT_HIDDEN);
@ -249,8 +230,8 @@ class Collapse extends BaseComponent {
this._queueCallback(complete, this._element, true);
}
setTransitioning(isTransitioning) {
this._isTransitioning = isTransitioning;
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
}
// Private
@ -258,39 +239,40 @@ class Collapse extends BaseComponent {
_getConfig(config) {
config = {
...Default,
...Manipulator.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(WIDTH) ? WIDTH : HEIGHT;
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
}
_getParent() {
let { parent } = this._config;
parent = getElement(parent);
const selector = `${SELECTOR_DATA_TOGGLE}[data-bs-parent="${parent}"]`;
SelectorEngine.find(selector, parent).forEach((element) => {
const selected = getElementFromSelector(element);
this._addAriaAndCollapsedClass(selected, [element]);
});
return parent;
}
_addAriaAndCollapsedClass(element, triggerArray) {
if (!element || !triggerArray.length) {
_initializeChildren() {
if (!this._config.parent) {
return;
}
const isOpen = element.classList.contains(CLASS_NAME_SHOW);
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
SelectorEngine.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) {
@ -305,21 +287,14 @@ class Collapse extends BaseComponent {
// Static
static collapseInterface(element, config) {
let data = Data.get(element, DATA_KEY);
const _config = {
...Default,
...Manipulator.getDataAttributes(element),
...(typeof config === 'object' && config ? config : {}),
};
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
static jQueryInterface(config) {
return this.each(function () {
const _config = {};
if (typeof config === 'string' && /show|hide/.test(config)) {
_config.toggle = false;
}
if (!data) {
data = new Collapse(element, _config);
}
const data = Collapse.getOrCreateInstance(this, _config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -328,11 +303,6 @@ class Collapse extends BaseComponent {
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Collapse.collapseInterface(this, config);
});
}
}
@ -352,26 +322,11 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
event.preventDefault();
}
const triggerData = Manipulator.getDataAttributes(this);
const selector = getSelectorFromElement(this);
const selectorElements = SelectorEngine.find(selector);
selectorElements.forEach((element) => {
const data = Data.get(element, DATA_KEY);
let config;
if (data) {
// update parent attribute
if (data._parent === null && typeof triggerData.parent === 'string') {
data._config.parent = triggerData.parent;
data._parent = data._getParent();
}
config = 'toggle';
} else {
config = triggerData;
}
Collapse.collapseInterface(element, config);
Collapse.getOrCreateInstance(element, { toggle: false }).toggle();
});
});

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/data.js
* Bootstrap (v5.1.3): dom/data.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/event-handler.js
* Bootstrap (v5.1.3): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -113,7 +113,6 @@ function bootstrapDelegationHandler(element, selector, fn) {
event.delegateTarget = target;
if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, selector, fn);
}

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/manipulator.js
* Bootstrap (v5.1.3): dom/manipulator.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -64,8 +64,8 @@ const Manipulator = {
const rect = element.getBoundingClientRect();
return {
top: rect.top + document.body.scrollTop,
left: rect.left + document.body.scrollLeft,
top: rect.top + window.pageYOffset,
left: rect.left + window.pageXOffset,
};
},

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dom/selector-engine.js
* Bootstrap (v5.1.3): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -11,6 +11,8 @@
* ------------------------------------------------------------------------
*/
import { isDisabled, isVisible } from '../util/index';
const NODE_TEXT = 3;
const SelectorEngine = {
@ -69,6 +71,23 @@ const SelectorEngine = {
return [];
},
focusableChildren(element) {
const focusables = [
'a',
'button',
'input',
'textarea',
'select',
'details',
'[tabindex]',
'[contenteditable="true"]',
]
.map((selector) => `${selector}:not([tabindex^="-"])`)
.join(', ');
return this.find(focusables, element).filter((el) => !isDisabled(el) && isVisible(el));
},
};
export default SelectorEngine;

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): dropdown.js
* Bootstrap (v5.1.3): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -11,14 +11,14 @@ import {
defineJQueryPlugin,
getElement,
getElementFromSelector,
getNextActiveElement,
isDisabled,
isElement,
isVisible,
isRTL,
isVisible,
noop,
typeCheckConfig,
} from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
@ -48,7 +48,6 @@ const EVENT_HIDE = `hide${EVENT_KEY}`;
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const EVENT_CLICK = `click${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
@ -103,8 +102,6 @@ class Dropdown extends BaseComponent {
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._inNavbar = this._detectNavbar();
this._addEventListeners();
}
// Getters
@ -124,26 +121,14 @@ class Dropdown extends BaseComponent {
// Public
toggle() {
if (isDisabled(this._element)) {
return;
}
const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
if (isActive) {
this.hide();
return;
}
this.show();
return this._isShown() ? this.hide() : this.show();
}
show() {
if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || this._isShown(this._menu)) {
return;
}
const parent = Dropdown.getParentFromElement(this._element);
const relatedTarget = {
relatedTarget: this._element,
};
@ -154,34 +139,12 @@ class Dropdown extends BaseComponent {
return;
}
const parent = Dropdown.getParentFromElement(this._element);
// Totally disable Popper for Dropdowns in Navbar
if (this._inNavbar) {
Manipulator.setDataAttribute(this._menu, 'popper', 'none');
} else {
if (typeof Popper === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator.setDataAttribute(this._menu, 'popper', 'static');
}
this._createPopper(parent);
}
// If this is a touch-enabled device we add extra
@ -197,13 +160,13 @@ class Dropdown extends BaseComponent {
this._element.focus();
this._element.setAttribute('aria-expanded', true);
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
this._menu.classList.add(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_SHOWN, relatedTarget);
}
hide() {
if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
if (isDisabled(this._element) || !this._isShown(this._menu)) {
return;
}
@ -231,13 +194,6 @@ class Dropdown extends BaseComponent {
// Private
_addEventListeners() {
EventHandler.on(this._element, EVENT_CLICK, (event) => {
event.preventDefault();
this.toggle();
});
}
_completeHide(relatedTarget) {
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget);
if (hideEvent.defaultPrevented) {
@ -286,6 +242,37 @@ class Dropdown extends BaseComponent {
return config;
}
_createPopper(parent) {
if (typeof Popper === 'undefined') {
throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");
}
let referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (isElement(this._config.reference)) {
referenceElement = getElement(this._config.reference);
} else if (typeof this._config.reference === 'object') {
referenceElement = this._config.reference;
}
const popperConfig = this._getPopperConfig();
const isDisplayStatic = popperConfig.modifiers.find(
(modifier) => modifier.name === 'applyStyles' && modifier.enabled === false
);
this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);
if (isDisplayStatic) {
Manipulator.setDataAttribute(this._menu, 'popper', 'static');
}
}
_isShown(element = this._element) {
return element.classList.contains(CLASS_NAME_SHOW);
}
_getMenuElement() {
return SelectorEngine.next(this._element, SELECTOR_MENU)[0];
}
@ -366,53 +353,33 @@ class Dropdown extends BaseComponent {
};
}
_selectMenuItem(event) {
_selectMenuItem({ key, target }) {
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);
if (!items.length) {
return;
}
let index = items.indexOf(event.target);
// Up
if (event.key === ARROW_UP_KEY && index > 0) {
index--;
}
// Down
if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
index++;
}
// index is -1 if the first keydown is an ArrowUp
index = index === -1 ? 0 : index;
items[index].focus();
// if target isn't included in items (e.g. when expanding the dropdown)
// allow cycling to get the last item in case key equals ARROW_UP_KEY
getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
}
// Static
static dropdownInterface(element, config) {
let data = Data.get(element, DATA_KEY);
const _config = typeof config === 'object' ? config : null;
static jQueryInterface(config) {
return this.each(function () {
const data = Dropdown.getOrCreateInstance(this, config);
if (!data) {
data = new Dropdown(element, _config);
if (typeof config !== 'string') {
return;
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError(`No method named "${config}"`);
}
data[config]();
}
}
static jQueryInterface(config) {
return this.each(function () {
Dropdown.dropdownInterface(this, config);
});
}
@ -427,12 +394,12 @@ class Dropdown extends BaseComponent {
const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE);
for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data.get(toggles[i], DATA_KEY);
const context = Dropdown.getInstance(toggles[i]);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
if (!context._isShown()) {
continue;
}
@ -505,28 +472,28 @@ class Dropdown extends BaseComponent {
return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE)
? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
const instance = Dropdown.getOrCreateInstance(getToggleButton);
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus();
instance.hide();
return;
}
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
getToggleButton().click();
if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
if (!isActive) {
instance.show();
}
instance._selectMenuItem(event);
return;
}
if (!isActive || event.key === SPACE_KEY) {
Dropdown.clearMenus();
return;
}
Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
}
}
@ -547,7 +514,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault();
Dropdown.dropdownInterface(this);
Dropdown.getOrCreateInstance(this).toggle();
});
/**

View File

@ -1,15 +1,13 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): modal.js
* Bootstrap (v5.1.3): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import {
defineJQueryPlugin,
emulateTransitionEnd,
getElementFromSelector,
getTransitionDurationFromElement,
isRTL,
isVisible,
reflow,
@ -18,13 +16,11 @@ import {
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine';
import {
getWidth as getScrollBarWidth,
hide as scrollBarHide,
reset as scrollBarReset,
} from './util/scrollbar';
import ScrollBarHelper from './util/scrollbar';
import BaseComponent from './base-component';
import Backdrop from './util/backdrop';
import FocusTrap from './util/focustrap';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -55,7 +51,6 @@ 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}`;
@ -68,10 +63,10 @@ const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_STATIC = 'modal-static';
const OPEN_SELECTOR = '.modal.show';
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"]';
/**
* ------------------------------------------------------------------------
@ -86,9 +81,11 @@ class Modal extends BaseComponent {
this._config = this._getConfig(config);
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
this._backdrop = this._initializeBackDrop();
this._focustrap = this._initializeFocusTrap();
this._isShown = false;
this._ignoreBackdropClick = false;
this._isTransitioning = false;
this._scrollBar = new ScrollBarHelper();
}
// Getters
@ -112,21 +109,21 @@ class Modal extends BaseComponent {
return;
}
if (this._isAnimated()) {
this._isTransitioning = true;
}
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
relatedTarget,
});
if (this._isShown || showEvent.defaultPrevented) {
if (showEvent.defaultPrevented) {
return;
}
this._isShown = true;
scrollBarHide();
if (this._isAnimated()) {
this._isTransitioning = true;
}
this._scrollBar.hide();
document.body.classList.add(CLASS_NAME_OPEN);
@ -135,10 +132,6 @@ class Modal extends BaseComponent {
this._setEscapeEvent();
this._setResizeEvent();
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, (event) =>
this.hide(event)
);
EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, (event) => {
if (event.target === this._element) {
@ -150,11 +143,7 @@ class Modal extends BaseComponent {
this._showBackdrop(() => this._showElement(relatedTarget));
}
hide(event) {
if (event) {
event.preventDefault();
}
hide() {
if (!this._isShown || this._isTransitioning) {
return;
}
@ -175,7 +164,7 @@ class Modal extends BaseComponent {
this._setEscapeEvent();
this._setResizeEvent();
EventHandler.off(document, EVENT_FOCUSIN);
this._focustrap.deactivate();
this._element.classList.remove(CLASS_NAME_SHOW);
@ -189,14 +178,8 @@ class Modal extends BaseComponent {
[window, this._dialog].forEach((htmlElement) => EventHandler.off(htmlElement, EVENT_KEY));
this._backdrop.dispose();
this._focustrap.deactivate();
super.dispose();
/**
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
* Do not move `document` in `htmlElements` array
* It will remove `EVENT_CLICK_DATA_API` event that should remain
*/
EventHandler.off(document, EVENT_FOCUSIN);
}
handleUpdate() {
@ -212,11 +195,17 @@ class Modal extends BaseComponent {
});
}
_initializeFocusTrap() {
return new FocusTrap({
trapElement: this._element,
});
}
_getConfig(config) {
config = {
...Default,
...Manipulator.getDataAttributes(this._element),
...config,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
@ -228,7 +217,7 @@ class Modal extends BaseComponent {
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
// Don't move modal's DOM position
document.body.appendChild(this._element);
document.body.append(this._element);
}
this._element.style.display = 'block';
@ -247,13 +236,9 @@ class Modal extends BaseComponent {
this._element.classList.add(CLASS_NAME_SHOW);
if (this._config.focus) {
this._enforceFocus();
}
const transitionComplete = () => {
if (this._config.focus) {
this._element.focus();
this._focustrap.activate();
}
this._isTransitioning = false;
@ -265,19 +250,6 @@ class Modal extends BaseComponent {
this._queueCallback(transitionComplete, this._dialog, isAnimated);
}
_enforceFocus() {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => {
if (
document !== event.target &&
this._element !== event.target &&
!this._element.contains(event.target)
) {
this._element.focus();
}
});
}
_setEscapeEvent() {
if (this._isShown) {
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
@ -310,7 +282,7 @@ class Modal extends BaseComponent {
this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN);
this._resetAdjustments();
scrollBarReset();
this._scrollBar.reset();
EventHandler.trigger(this._element, EVENT_HIDDEN);
});
}
@ -346,25 +318,31 @@ class Modal extends BaseComponent {
return;
}
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const { classList, scrollHeight, style } = this._element;
const isModalOverflowing = scrollHeight > document.documentElement.clientHeight;
if (!isModalOverflowing) {
this._element.style.overflowY = 'hidden';
// return if the following background transition hasn't yet completed
if (
(!isModalOverflowing && style.overflowY === 'hidden') ||
classList.contains(CLASS_NAME_STATIC)
) {
return;
}
this._element.classList.add(CLASS_NAME_STATIC);
const modalTransitionDuration = getTransitionDurationFromElement(this._dialog);
EventHandler.off(this._element, 'transitionend');
EventHandler.one(this._element, 'transitionend', () => {
this._element.classList.remove(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
EventHandler.one(this._element, 'transitionend', () => {
this._element.style.overflowY = '';
});
emulateTransitionEnd(this._element, modalTransitionDuration);
style.overflowY = 'hidden';
}
});
emulateTransitionEnd(this._element, modalTransitionDuration);
classList.add(CLASS_NAME_STATIC);
this._queueCallback(() => {
classList.remove(CLASS_NAME_STATIC);
if (!isModalOverflowing) {
this._queueCallback(() => {
style.overflowY = '';
}, this._dialog);
}
}, this._dialog);
this._element.focus();
}
@ -374,7 +352,7 @@ class Modal extends BaseComponent {
_adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getScrollBarWidth();
const scrollbarWidth = this._scrollBar.getWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if (
@ -401,8 +379,7 @@ class Modal extends BaseComponent {
static jQueryInterface(config, relatedTarget) {
return this.each(function () {
const data =
Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
const data = Modal.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -443,11 +420,19 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
});
});
const data = Modal.getInstance(target) || new Modal(target);
// avoid conflict when clicking moddal toggler while another one is open
const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
if (allReadyOpen) {
Modal.getInstance(allReadyOpen).hide();
}
const data = Modal.getOrCreateInstance(target);
data.toggle(this);
});
enableDismissTrigger(Modal);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,7 +1,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Bootstrap (v5.1.3): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -12,13 +12,14 @@ import {
isVisible,
typeCheckConfig,
} from './util/index';
import { hide as scrollBarHide, reset as scrollBarReset } from './util/scrollbar';
import Data from './dom/data';
import ScrollBarHelper from './util/scrollbar';
import EventHandler from './dom/event-handler';
import BaseComponent from './base-component';
import SelectorEngine from './dom/selector-engine';
import Manipulator from './dom/manipulator';
import Backdrop from './util/backdrop';
import FocusTrap from './util/focustrap';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -46,18 +47,16 @@ const DefaultType = {
};
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"]';
/**
@ -73,6 +72,7 @@ class Offcanvas extends BaseComponent {
this._config = this._getConfig(config);
this._isShown = false;
this._backdrop = this._initializeBackDrop();
this._focustrap = this._initializeFocusTrap();
this._addEventListeners();
}
@ -109,8 +109,7 @@ class Offcanvas extends BaseComponent {
this._backdrop.show();
if (!this._config.scroll) {
scrollBarHide();
this._enforceFocusOnElement(this._element);
new ScrollBarHelper().hide();
}
this._element.removeAttribute('aria-hidden');
@ -119,6 +118,10 @@ class Offcanvas extends BaseComponent {
this._element.classList.add(CLASS_NAME_SHOW);
const completeCallBack = () => {
if (!this._config.scroll) {
this._focustrap.activate();
}
EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget });
};
@ -136,7 +139,7 @@ class Offcanvas extends BaseComponent {
return;
}
EventHandler.off(document, EVENT_FOCUSIN);
this._focustrap.deactivate();
this._element.blur();
this._isShown = false;
this._element.classList.remove(CLASS_NAME_SHOW);
@ -149,7 +152,7 @@ class Offcanvas extends BaseComponent {
this._element.style.visibility = 'hidden';
if (!this._config.scroll) {
scrollBarReset();
new ScrollBarHelper().reset();
}
EventHandler.trigger(this._element, EVENT_HIDDEN);
@ -160,8 +163,8 @@ class Offcanvas extends BaseComponent {
dispose() {
this._backdrop.dispose();
this._focustrap.deactivate();
super.dispose();
EventHandler.off(document, EVENT_FOCUSIN);
}
// Private
@ -178,6 +181,7 @@ class Offcanvas extends BaseComponent {
_initializeBackDrop() {
return new Backdrop({
className: CLASS_NAME_BACKDROP,
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
@ -185,23 +189,13 @@ class Offcanvas extends BaseComponent {
});
}
_enforceFocusOnElement(element) {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.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.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.key === ESCAPE_KEY) {
this.hide();
@ -213,8 +207,7 @@ class Offcanvas extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data =
Data.get(this, DATA_KEY) || new Offcanvas(this, typeof config === 'object' ? config : {});
const data = Offcanvas.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;
@ -259,17 +252,15 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
Offcanvas.getInstance(allReadyOpen).hide();
}
const data = Data.get(target, DATA_KEY) || new Offcanvas(target);
const data = Offcanvas.getOrCreateInstance(target);
data.toggle(this);
});
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine.find(OPEN_SELECTOR).forEach((el) =>
(Data.get(el, DATA_KEY) || new Offcanvas(el)).show()
);
});
EventHandler.on(window, EVENT_LOAD_DATA_API, () =>
SelectorEngine.find(OPEN_SELECTOR).forEach((el) => Offcanvas.getOrCreateInstance(el).show())
);
enableDismissTrigger(Offcanvas);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,13 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): popover.js
* Bootstrap (v5.1.3): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin } from './util/index';
import Data from './dom/data';
import SelectorEngine from './dom/selector-engine';
import Tooltip from './tooltip';
/**
@ -20,7 +18,6 @@ const NAME = 'popover';
const DATA_KEY = 'bs.popover';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-popover';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const Default = {
...Tooltip.Default,
@ -54,9 +51,6 @@ const Event = {
MOUSELEAVE: `mouseleave${EVENT_KEY}`,
};
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const SELECTOR_TITLE = '.popover-header';
const SELECTOR_CONTENT = '.popover-body';
@ -91,54 +85,26 @@ class Popover extends Tooltip {
return this.getTitle() || this._getContent();
}
setContent() {
const tip = this.getTipElement();
// we use append for html objects to maintain js events
this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle());
let content = this._getContent();
if (typeof content === 'function') {
content = content.call(this._element);
}
this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TITLE);
this._sanitizeAndSetContent(tip, this._getContent(), SELECTOR_CONTENT);
}
// Private
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
}
_getContent() {
return this._element.getAttribute('data-bs-content') || this._config.content;
return this._resolvePossibleFunction(this._config.content);
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' ? config : null;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Popover(this, _config);
Data.set(this, DATA_KEY, data);
}
const data = Popover.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

View File

@ -1,15 +1,14 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): scrollspy.js
* Bootstrap (v5.1.3): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import {
defineJQueryPlugin,
getElement,
getSelectorFromElement,
getUID,
isElement,
typeCheckConfig,
} from './util/index';
import EventHandler from './dom/event-handler';
@ -52,6 +51,7 @@ const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
const SELECTOR_NAV_LINKS = '.nav-link';
const SELECTOR_NAV_ITEMS = '.nav-item';
const SELECTOR_LIST_ITEMS = '.list-group-item';
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}, .${CLASS_NAME_DROPDOWN_ITEM}`;
const SELECTOR_DROPDOWN = '.dropdown';
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
@ -69,7 +69,6 @@ class ScrollSpy extends BaseComponent {
super(element);
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
this._config = this._getConfig(config);
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`;
this._offsets = [];
this._targets = [];
this._activeTarget = null;
@ -105,7 +104,7 @@ class ScrollSpy extends BaseComponent {
this._targets = [];
this._scrollHeight = this._getScrollHeight();
const targets = SelectorEngine.find(this._selector);
const targets = SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target);
targets
.map((element) => {
@ -143,15 +142,7 @@ class ScrollSpy extends BaseComponent {
...(typeof config === 'object' && config ? config : {}),
};
if (typeof config.target !== 'string' && isElement(config.target)) {
let { id } = config.target;
if (!id) {
id = getUID(NAME);
config.target.id = id;
}
config.target = `#${id}`;
}
config.target = getElement(config.target) || document.documentElement;
typeCheckConfig(NAME, config, DefaultType);
@ -219,30 +210,25 @@ class ScrollSpy extends BaseComponent {
this._clear();
const queries = this._selector
.split(',')
.map((selector) => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`);
const queries = SELECTOR_LINK_ITEMS.split(',').map(
(selector) => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`
);
const link = SelectorEngine.findOne(queries.join(','));
const link = SelectorEngine.findOne(queries.join(','), this._config.target);
link.classList.add(CLASS_NAME_ACTIVE);
if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
SelectorEngine.findOne(
SELECTOR_DROPDOWN_TOGGLE,
link.closest(SELECTOR_DROPDOWN)
).classList.add(CLASS_NAME_ACTIVE);
link.classList.add(CLASS_NAME_ACTIVE);
} else {
// Set triggered link as active
link.classList.add(CLASS_NAME_ACTIVE);
SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP).forEach((listGroup) => {
// Set triggered links parents as active
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
SelectorEngine.prev(
listGroup,
`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`
).forEach((item) => item.classList.add(CLASS_NAME_ACTIVE));
SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(
(item) => item.classList.add(CLASS_NAME_ACTIVE)
);
// Handle special case when .nav-link is inside .nav-item
SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach((navItem) => {
@ -259,7 +245,7 @@ class ScrollSpy extends BaseComponent {
}
_clear() {
SelectorEngine.find(this._selector)
SelectorEngine.find(SELECTOR_LINK_ITEMS, this._config.target)
.filter((node) => node.classList.contains(CLASS_NAME_ACTIVE))
.forEach((node) => node.classList.remove(CLASS_NAME_ACTIVE));
}
@ -268,9 +254,7 @@ class ScrollSpy extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data =
ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
const data = ScrollSpy.getOrCreateInstance(this, config);
if (typeof config !== 'string') {
return;

View File

@ -1,12 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tab.js
* Bootstrap (v5.1.3): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, getElementFromSelector, isDisabled, reflow } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import SelectorEngine from './dom/selector-engine';
import BaseComponent from './base-component';
@ -187,7 +186,7 @@ class Tab extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
const data = Data.get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -215,7 +214,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
return;
}
const data = Data.get(this, DATA_KEY) || new Tab(this);
const data = Tab.getOrCreateInstance(this);
data.show();
});

View File

@ -1,15 +1,15 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): toast.js
* Bootstrap (v5.1.3): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import { defineJQueryPlugin, reflow, typeCheckConfig } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator';
import BaseComponent from './base-component';
import { enableDismissTrigger } from './util/component-functions';
/**
* ------------------------------------------------------------------------
@ -21,7 +21,6 @@ const NAME = 'toast';
const DATA_KEY = 'bs.toast';
const EVENT_KEY = `.${DATA_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
@ -32,7 +31,7 @@ const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`;
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_HIDE = 'hide';
const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_SHOWING = 'showing';
@ -48,8 +47,6 @@ const Default = {
delay: 5000,
};
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="toast"]';
/**
* ------------------------------------------------------------------------
* Class Definition
@ -98,15 +95,14 @@ class Toast extends BaseComponent {
const complete = () => {
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.add(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_SHOWN);
this._maybeScheduleHide();
};
this._element.classList.remove(CLASS_NAME_HIDE);
this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
reflow(this._element);
this._element.classList.add(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
@ -124,11 +120,13 @@ class Toast extends BaseComponent {
}
const complete = () => {
this._element.classList.add(CLASS_NAME_HIDE);
this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
this._element.classList.remove(CLASS_NAME_SHOWING);
this._element.classList.remove(CLASS_NAME_SHOW);
EventHandler.trigger(this._element, EVENT_HIDDEN);
};
this._element.classList.remove(CLASS_NAME_SHOW);
this._element.classList.add(CLASS_NAME_SHOWING);
this._queueCallback(complete, this._element, this._config.animation);
}
@ -198,7 +196,6 @@ class Toast extends BaseComponent {
}
_setListeners() {
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(this._element, EVENT_MOUSEOVER, (event) => this._onInteraction(event, true));
EventHandler.on(this._element, EVENT_MOUSEOUT, (event) => this._onInteraction(event, false));
EventHandler.on(this._element, EVENT_FOCUSIN, (event) => this._onInteraction(event, true));
@ -214,12 +211,7 @@ class Toast extends BaseComponent {
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data) {
data = new Toast(this, _config);
}
const data = Toast.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
@ -232,6 +224,8 @@ class Toast extends BaseComponent {
}
}
enableDismissTrigger(Toast);
/**
* ------------------------------------------------------------------------
* jQuery

View File

@ -1,6 +1,6 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): tooltip.js
* Bootstrap (v5.1.3): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -34,7 +34,6 @@ const NAME = 'tooltip';
const DATA_KEY = 'bs.tooltip';
const EVENT_KEY = `.${DATA_KEY}`;
const CLASS_PREFIX = 'bs-tooltip';
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
const DefaultType = {
@ -110,6 +109,9 @@ const HOVER_STATE_SHOW = 'show';
const HOVER_STATE_OUT = 'out';
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
const EVENT_MODAL_HIDE = 'hide.bs.modal';
const TRIGGER_HOVER = 'hover';
const TRIGGER_FOCUS = 'focus';
@ -205,19 +207,16 @@ class Tooltip extends BaseComponent {
clearTimeout(this._timeout);
EventHandler.off(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
if (this.tip && this.tip.parentNode) {
this.tip.parentNode.removeChild(this.tip);
}
if (this._popper) {
this._popper.destroy();
if (this.tip) {
this.tip.remove();
}
this._disposePopper();
super.dispose();
}
@ -241,14 +240,24 @@ class Tooltip extends BaseComponent {
return;
}
// A trick to recreate a tooltip in case a new title is given by using the NOT documented `data-bs-original-title`
// This will be removed later in favor of a `setContent` method
if (
this.constructor.NAME === 'tooltip' &&
this.tip &&
this.getTitle() !== this.tip.querySelector(SELECTOR_TOOLTIP_INNER).innerHTML
) {
this._disposePopper();
this.tip.remove();
this.tip = null;
}
const tip = this.getTipElement();
const tipId = getUID(this.constructor.NAME);
tip.setAttribute('id', tipId);
this._element.setAttribute('aria-describedby', tipId);
this.setContent();
if (this._config.animation) {
tip.classList.add(CLASS_NAME_FADE);
}
@ -265,7 +274,7 @@ class Tooltip extends BaseComponent {
Data.set(tip, this.constructor.DATA_KEY, this);
if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
container.appendChild(tip);
container.append(tip);
EventHandler.trigger(this._element, this.constructor.Event.INSERTED);
}
@ -277,10 +286,7 @@ class Tooltip extends BaseComponent {
tip.classList.add(CLASS_NAME_SHOW);
const customClass =
typeof this._config.customClass === 'function'
? this._config.customClass()
: this._config.customClass;
const customClass = this._resolvePossibleFunction(this._config.customClass);
if (customClass) {
tip.classList.add(...customClass.split(' '));
}
@ -321,18 +327,15 @@ class Tooltip extends BaseComponent {
return;
}
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip);
if (this._hoverState !== HOVER_STATE_SHOW) {
tip.remove();
}
this._cleanTipClass();
this._element.removeAttribute('aria-describedby');
EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
this._disposePopper();
};
const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);
@ -379,14 +382,28 @@ class Tooltip extends BaseComponent {
const element = document.createElement('div');
element.innerHTML = this._config.template;
this.tip = element.children[0];
const tip = element.children[0];
this.setContent(tip);
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
this.tip = tip;
return this.tip;
}
setContent() {
const tip = this.getTipElement();
this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle());
tip.classList.remove(CLASS_NAME_FADE, CLASS_NAME_SHOW);
setContent(tip) {
this._sanitizeAndSetContent(tip, this.getTitle(), SELECTOR_TOOLTIP_INNER);
}
_sanitizeAndSetContent(template, content, selector) {
const templateElement = SelectorEngine.findOne(selector, template);
if (!content && templateElement) {
templateElement.remove();
return;
}
// we use append for html objects to maintain js events
this.setElementContent(templateElement, content);
}
setElementContent(element, content) {
@ -401,7 +418,7 @@ class Tooltip extends BaseComponent {
if (this._config.html) {
if (content.parentNode !== element) {
element.innerHTML = '';
element.appendChild(content);
element.append(content);
}
} else {
element.textContent = content.textContent;
@ -422,16 +439,9 @@ class Tooltip extends BaseComponent {
}
getTitle() {
let title = this._element.getAttribute('data-bs-original-title');
const title = this._element.getAttribute('data-bs-original-title') || this._config.title;
if (!title) {
title =
typeof this._config.title === 'function'
? this._config.title.call(this._element)
: this._config.title;
}
return title;
return this._resolvePossibleFunction(title);
}
updateAttachment(attachment) {
@ -449,15 +459,10 @@ class Tooltip extends BaseComponent {
// Private
_initializeOnDelegatedTarget(event, context) {
const dataKey = this.constructor.DATA_KEY;
context = context || Data.get(event.delegateTarget, dataKey);
if (!context) {
context = new this.constructor(event.delegateTarget, this._getDelegateConfig());
Data.set(event.delegateTarget, dataKey, context);
}
return context;
return (
context ||
this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig())
);
}
_getOffset() {
@ -474,6 +479,10 @@ class Tooltip extends BaseComponent {
return offset;
}
_resolvePossibleFunction(content) {
return typeof content === 'function' ? content.call(this._element) : content;
}
_getPopperConfig(attachment) {
const defaultBsPopperConfig = {
placement: attachment,
@ -525,7 +534,9 @@ class Tooltip extends BaseComponent {
}
_addAttachmentClass(attachment) {
this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
this.getTipElement().classList.add(
`${this._getBasicClassPrefix()}-${this.updateAttachment(attachment)}`
);
}
_getAttachment(placement) {
@ -569,8 +580,8 @@ class Tooltip extends BaseComponent {
};
EventHandler.on(
this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal',
this._element.closest(SELECTOR_MODAL),
EVENT_MODAL_HIDE,
this._hideModalHandler
);
@ -634,9 +645,8 @@ class Tooltip extends BaseComponent {
context = this._initializeOnDelegatedTarget(event, context);
if (event) {
context._activeTrigger[
event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER
] = context._element.contains(event.relatedTarget);
context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] =
context._element.contains(event.relatedTarget);
}
if (context._isWithActiveTrigger()) {
@ -713,25 +723,31 @@ class Tooltip extends BaseComponent {
_getDelegateConfig() {
const config = {};
if (this._config) {
for (const key in this._config) {
if (this.constructor.Default[key] !== this._config[key]) {
config[key] = this._config[key];
}
}
}
// In the future can be replaced with:
// const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
// `Object.fromEntries(keysWithDifferentValues)`
return config;
}
_cleanTipClass() {
const tip = this.getTipElement();
const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
const basicClassPrefixRegex = new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`, 'g');
const tabClass = tip.getAttribute('class').match(basicClassPrefixRegex);
if (tabClass !== null && tabClass.length > 0) {
tabClass.map((token) => token.trim()).forEach((tClass) => tip.classList.remove(tClass));
}
}
_getBasicClassPrefix() {
return CLASS_PREFIX;
}
_handlePopperPlacementChange(popperData) {
const { state } = popperData;
@ -744,20 +760,18 @@ class Tooltip extends BaseComponent {
this._addAttachmentClass(this._getAttachment(state.placement));
}
_disposePopper() {
if (this._popper) {
this._popper.destroy();
this._popper = null;
}
}
// Static
static jQueryInterface(config) {
return this.each(function () {
let data = Data.get(this, DATA_KEY);
const _config = typeof config === 'object' && config;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Tooltip(this, _config);
}
const data = Tooltip.getOrCreateInstance(this, config);
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {

View File

@ -1,34 +1,29 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): 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)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import {
emulateTransitionEnd,
execute,
getTransitionDurationFromElement,
reflow,
typeCheckConfig,
} from './index';
import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index';
const Default = {
className: 'modal-backdrop',
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
rootElement: 'body', // give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType = {
className: 'string',
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
rootElement: '(element|string)',
clickCallback: '(function|null)',
};
const NAME = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
@ -79,7 +74,7 @@ class Backdrop {
_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);
}
@ -96,7 +91,8 @@ class Backdrop {
...(typeof config === 'object' ? config : {}),
};
config.rootElement = config.rootElement || document.body;
// use getElement() with the default "body" to get a fresh Element on each instantiation
config.rootElement = getElement(config.rootElement);
typeCheckConfig(NAME, config, DefaultType);
return config;
}
@ -106,7 +102,7 @@ class Backdrop {
return;
}
this._config.rootElement.appendChild(this._getElement());
this._config.rootElement.append(this._getElement());
EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
@ -122,19 +118,12 @@ class Backdrop {
EventHandler.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._element.remove();
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler.one(this._getElement(), 'transitionend', () => execute(callback));
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
}
}

View File

@ -0,0 +1,32 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/component-functions.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import { getElementFromSelector, isDisabled } from './index';
const enableDismissTrigger = (component, method = 'hide') => {
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
const name = component.NAME;
EventHandler.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]();
});
};
export { enableDismissTrigger };

View File

@ -0,0 +1,105 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.1.3): util/focustrap.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import SelectorEngine from '../dom/selector-engine';
import { typeCheckConfig } from './index';
const Default = {
trapElement: null, // The element to trap focus inside of
autofocus: true,
};
const DefaultType = {
trapElement: 'element',
autofocus: 'boolean',
};
const NAME = 'focustrap';
const DATA_KEY = 'bs.focustrap';
const EVENT_KEY = `.${DATA_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`;
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.off(document, EVENT_KEY); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => this._handleFocusin(event));
EventHandler.on(document, EVENT_KEYDOWN_TAB, (event) => this._handleKeydown(event));
this._isActive = true;
}
deactivate() {
if (!this._isActive) {
return;
}
this._isActive = false;
EventHandler.off(document, EVENT_KEY);
}
// Private
_handleFocusin(event) {
const { target } = event;
const { trapElement } = this._config;
if (target === document || target === trapElement || trapElement.contains(target)) {
return;
}
const elements = SelectorEngine.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,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
}
}
export default FocusTrap;

View File

@ -1,8 +1,6 @@
import SelectorEngine from '../dom/selector-engine';
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/index.js
* Bootstrap (v5.1.3): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
@ -127,30 +125,12 @@ const getElement = (obj) => {
}
if (typeof obj === 'string' && obj.length > 0) {
return SelectorEngine.findOne(obj);
return document.querySelector(obj);
}
return null;
};
const emulateTransitionEnd = (element, duration) => {
let called = false;
const durationPadding = 5;
const emulatedDuration = duration + durationPadding;
function listener() {
called = true;
element.removeEventListener(TRANSITION_END, listener);
}
element.addEventListener(TRANSITION_END, listener);
setTimeout(() => {
if (!called) {
triggerTransitionEnd(element);
}
}, emulatedDuration);
};
const typeCheckConfig = (componentName, config, configTypes) => {
Object.keys(configTypes).forEach((property) => {
const expectedTypes = configTypes[property];
@ -166,22 +146,11 @@ const typeCheckConfig = (componentName, config, configTypes) => {
};
const isVisible = (element) => {
if (!element) {
if (!isElement(element) || element.getClientRects().length === 0) {
return false;
}
if (element.style && element.parentNode && element.parentNode.style) {
const elementStyle = getComputedStyle(element);
const parentNodeStyle = getComputedStyle(element.parentNode);
return (
elementStyle.display !== 'none' &&
parentNodeStyle.display !== 'none' &&
elementStyle.visibility !== 'hidden'
);
}
return false;
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
};
const isDisabled = (element) => {
@ -225,7 +194,18 @@ const findShadowRoot = (element) => {
const noop = () => {};
const reflow = (element) => element.offsetHeight;
/**
* 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;
@ -237,9 +217,18 @@ const getjQuery = () => {
return null;
};
const DOMContentLoadedCallbacks = [];
const onDOMContentLoaded = (callback) => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', callback);
// 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();
}
@ -270,6 +259,63 @@ const execute = (callback) => {
}
};
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);
};
/**
* Return the previous/next element of a list.
*
* @param {array} list The list of elements
* @param activeElement The active element
* @param shouldGetNext Choose to get next or previous element
* @param isCycleAllowed
* @return {Element|elem} The proper element
*/
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
let index = list.indexOf(activeElement);
// if the element does not exist in the list return an element depending on the direction and if cycle is allowed
if (index === -1) {
return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
}
const listLength = list.length;
index += shouldGetNext ? 1 : -1;
if (isCycleAllowed) {
index = (index + listLength) % listLength;
}
return list[Math.max(0, Math.min(index, listLength - 1))];
};
export {
getElement,
getUID,
@ -278,16 +324,17 @@ export {
getTransitionDurationFromElement,
triggerTransitionEnd,
isElement,
emulateTransitionEnd,
typeCheckConfig,
isVisible,
isDisabled,
findShadowRoot,
noop,
getNextActiveElement,
reflow,
getjQuery,
onDOMContentLoaded,
isRTL,
defineJQueryPlugin,
execute,
executeAfterTransition,
};

View File

@ -1,11 +1,11 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/sanitizer.js
* Bootstrap (v5.1.3): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
const uriAttrs = new Set([
const uriAttributes = new Set([
'background',
'cite',
'href',
@ -21,35 +21,36 @@ const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
/**
* A pattern that matches safe data URLs. Only matches image, video and audio types.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
* Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
*/
const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const DATA_URL_PATTERN =
/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
const allowedAttribute = (attr, allowedAttributeList) => {
const attrName = attr.nodeName.toLowerCase();
const allowedAttribute = (attribute, allowedAttributeList) => {
const attributeName = attribute.nodeName.toLowerCase();
if (allowedAttributeList.includes(attrName)) {
if (uriAttrs.has(attrName)) {
if (allowedAttributeList.includes(attributeName)) {
if (uriAttributes.has(attributeName)) {
return Boolean(
SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)
SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue)
);
}
return true;
}
const regExp = allowedAttributeList.filter((attrRegex) => attrRegex instanceof RegExp);
const regExp = allowedAttributeList.filter((attributeRegex) => attributeRegex instanceof RegExp);
// Check if a regular expression validates the attribute.
for (let i = 0, len = regExp.length; i < len; i++) {
if (regExp[i].test(attrName)) {
if (regExp[i].test(attributeName)) {
return true;
}
}
@ -102,25 +103,24 @@ export function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
const domParser = new window.DOMParser();
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
const allowlistKeys = Object.keys(allowList);
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
for (let i = 0, len = elements.length; i < len; i++) {
const el = elements[i];
const elName = el.nodeName.toLowerCase();
const element = elements[i];
const elementName = element.nodeName.toLowerCase();
if (!allowlistKeys.includes(elName)) {
el.parentNode.removeChild(el);
if (!Object.keys(allowList).includes(elementName)) {
element.remove();
continue;
}
const attributeList = [].concat(...el.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);
const attributeList = [].concat(...element.attributes);
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
attributeList.forEach((attr) => {
if (!allowedAttribute(attr, allowedAttributes)) {
el.removeAttribute(attr.nodeName);
attributeList.forEach((attribute) => {
if (!allowedAttribute(attribute, allowedAttributes)) {
element.removeAttribute(attribute.nodeName);
}
});
}

View File

@ -1,71 +1,86 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.1): util/scrollBar.js
* Bootstrap (v5.1.3): util/scrollBar.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/
import SelectorEngine from '../dom/selector-engine';
import Manipulator from '../dom/manipulator';
import { isElement } from './index';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => {
class ScrollBarHelper {
constructor() {
this._element = document.body;
}
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(
hide() {
const width = this.getWidth();
this._disableOverFlow();
// give padding to element to balance the hidden scrollbar width
this._setElementAttributes(
this._element,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
this._setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - width
);
};
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
};
_disableOverFlow() {
this._saveInitialAttribute(this._element, 'overflow');
this._element.style.overflow = 'hidden';
}
const _setElementAttributes = (selector, styleProp, callback) => {
const scrollbarWidth = getWidth();
SelectorEngine.find(selector).forEach((element) => {
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
_setElementAttributes(selector, styleProp, callback) {
const scrollbarWidth = this.getWidth();
const manipulationCallBack = (element) => {
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
return;
}
const actualValue = element.style[styleProp];
this._saveInitialAttribute(element, styleProp);
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.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');
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach((element) => {
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) {
Manipulator.setDataAttribute(element, styleProp, actualValue);
}
}
_resetElementAttributes(selector, styleProp) {
const manipulationCallBack = (element) => {
const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp);
@ -73,11 +88,22 @@ const _resetElementAttributes = (selector, styleProp) => {
Manipulator.removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
};
};
const isBodyOverflowing = () => {
return getWidth() > 0;
};
this._applyManipulationCallback(selector, manipulationCallBack);
}
export { getWidth, hide, isBodyOverflowing, reset };
_applyManipulationCallback(selector, callBack) {
if (isElement(selector)) {
callBack(selector);
} else {
SelectorEngine.find(selector, this._element).forEach(callBack);
}
}
isOverflowing() {
return this.getWidth() > 0;
}
}
export default ScrollBarHelper;

View File

@ -297,6 +297,12 @@ class Input {
static getInstance(element) {
return Data.getData(element, DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
}
EventHandler.on(document, 'focus', SELECTOR_OUTLINE_INPUT, Input.activate(new Input()));

View File

@ -118,6 +118,12 @@ class Range {
return Data.getData(element, DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
static jQueryInterface(config, options) {
return this.each(function () {
let data = Data.getData(this, DATA_KEY);

View File

@ -337,6 +337,12 @@ class Ripple {
static getInstance(element) {
return Data.getData(element, DATA_KEY);
}
static getOrCreateInstance(element, config = {}) {
return (
this.getInstance(element) || new this(element, typeof config === 'object' ? config : null)
);
}
}
/**

View File

@ -1,4 +1,3 @@
import TouchUtil from './touchUtil';
import EventHandler from '../../dom/event-handler';
const DEFAULT_OPTIONS = {
@ -6,9 +5,8 @@ const DEFAULT_OPTIONS = {
direction: 'all',
};
class Swipe extends TouchUtil {
class Swipe {
constructor(element, options) {
super();
this._element = element;
this._startPosition = null;
this._options = {
@ -57,6 +55,27 @@ class Swipe extends TouchUtil {
handleTouchEnd() {
this._startPosition = null;
}
_getCoordinates(e) {
const [touch] = e.touches;
return {
x: touch.clientX,
y: touch.clientY,
};
}
_getDirection(displacement) {
return {
x: {
direction: displacement.x < 0 ? 'left' : 'right',
value: Math.abs(displacement.x),
},
y: {
direction: displacement.y < 0 ? 'up' : 'down',
value: Math.abs(displacement.y),
},
};
}
}
export default Swipe;

View File

@ -13,6 +13,7 @@
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
@include box-shadow($card-box-shadow);
> hr {
margin-right: 0;
@ -55,7 +56,7 @@
}
.card-subtitle {
margin-top: -$card-title-spacer-y / 2;
margin-top: -$card-title-spacer-y * 0.5;
margin-bottom: 0;
}
@ -65,7 +66,7 @@
.card-link {
&:hover {
text-decoration: none;
text-decoration: if($link-hover-decoration == underline, none, null);
}
+ .card-link {
@ -105,9 +106,9 @@
//
.card-header-tabs {
margin-right: -$card-cap-padding-x / 2;
margin-right: -$card-cap-padding-x * 0.5;
margin-bottom: -$card-cap-padding-y;
margin-left: -$card-cap-padding-x / 2;
margin-left: -$card-cap-padding-x * 0.5;
border-bottom: 0;
@if $nav-tabs-link-active-bg != $card-bg {
@ -119,8 +120,8 @@
}
.card-header-pills {
margin-right: -$card-cap-padding-x / 2;
margin-left: -$card-cap-padding-x / 2;
margin-right: -$card-cap-padding-x * 0.5;
margin-left: -$card-cap-padding-x * 0.5;
}
// Card image

View File

@ -207,9 +207,9 @@
.carousel-caption {
position: absolute;
right: (100% - $carousel-caption-width) / 2;
right: (100% - $carousel-caption-width) * 0.5;
bottom: $carousel-caption-spacer;
left: (100% - $carousel-caption-width) / 2;
left: (100% - $carousel-caption-width) * 0.5;
padding-top: $carousel-caption-padding-y;
padding-bottom: $carousel-caption-padding-y;
color: $carousel-caption-color;

View File

@ -50,9 +50,7 @@
--bs-position: start;
&[data-mdb-popper] {
/*!rtl:ignore*/
right: auto;
/*!rtl:ignore*/
left: 0;
}
}
@ -61,9 +59,7 @@
--bs-position: end;
&[data-mdb-popper] {
/*!rtl:ignore*/
right: 0;
/*!rtl:ignore*/
left: auto;
}
}

Some files were not shown because too many files have changed in this diff Show More