release 3.6.0

This commit is contained in:
Grzegorz 2021-05-17 09:28:30 +02:00
parent f8c90e2b45
commit 42c95982a9
126 changed files with 2043 additions and 1445 deletions

View File

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

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

8
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

4
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

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", "name": "mdb-ui-kit",
"version": "3.5.1", "version": "3.6.0",
"main": "js/mdb.min.js", "main": "js/mdb.min.js",
"homepage": "https://mdbootstrap.com/docs/standard/", "homepage": "https://mdbootstrap.com/docs/standard/",
"repository": "https://github.com/mdbootstrap/mdb-ui-kit.git", "repository": "https://github.com/mdbootstrap/mdb-ui-kit.git",

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap alert.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap alert.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -27,7 +27,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -48,7 +48,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -143,7 +143,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): alert.js * Bootstrap (v5.0.0): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,16 @@
/*! /*!
* Bootstrap base-component.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap base-component.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
(function (global, factory) { (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory(require('./dom/data.js'))) ? (module.exports = factory(require('./dom/data.js'), require('./dom/event-handler.js')))
: typeof define === 'function' && define.amd : typeof define === 'function' && define.amd
? define(['./dom/data'], factory) ? define(['./dom/data', './dom/event-handler'], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Base = factory(global.Data))); (global.Base = factory(global.Data, global.EventHandler)));
})(this, function (Data) { })(this, function (Data, EventHandler) {
'use strict'; 'use strict';
function _interopDefaultLegacy(e) { function _interopDefaultLegacy(e) {
@ -18,10 +18,11 @@
} }
var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data); var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): base-component.js * Bootstrap (v5.0.0): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -31,7 +32,7 @@
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const VERSION = '5.0.0-beta3'; const VERSION = '5.0.0';
class BaseComponent { class BaseComponent {
constructor(element) { constructor(element) {
@ -47,6 +48,7 @@
dispose() { dispose() {
Data__default['default'].remove(this._element, this.constructor.DATA_KEY); Data__default['default'].remove(this._element, this.constructor.DATA_KEY);
EventHandler__default['default'].off(this._element, `.${this.constructor.DATA_KEY}`);
this._element = null; this._element = null;
} }
/** Static */ /** Static */

View File

@ -1 +1 @@
{"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0-beta3): base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst VERSION = '5.0.0-beta3'\n\nclass BaseComponent {\n constructor(element) {\n element = typeof element === 'string' ? document.querySelector(element) : element\n\n if (!element) {\n return\n }\n\n this._element = element\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n this._element = null\n }\n\n /** Static */\n\n static getInstance(element) {\n return Data.get(element, this.DATA_KEY)\n }\n\n static get VERSION() {\n return VERSION\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","constructor","element","document","querySelector","_element","Data","set","DATA_KEY","dispose","remove","getInstance","get"],"mappings":";;;;;;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;EAIA;EACA;EACA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,aAAhB;;EAEA,MAAMC,aAAN,CAAoB;EAClBC,EAAAA,WAAW,CAACC,OAAD,EAAU;EACnBA,IAAAA,OAAO,GAAG,OAAOA,OAAP,KAAmB,QAAnB,GAA8BC,QAAQ,CAACC,aAAT,CAAuBF,OAAvB,CAA9B,GAAgEA,OAA1E;;EAEA,QAAI,CAACA,OAAL,EAAc;EACZ;EACD;;EAED,SAAKG,QAAL,GAAgBH,OAAhB;EACAI,IAAAA,wBAAI,CAACC,GAAL,CAAS,KAAKF,QAAd,EAAwB,KAAKJ,WAAL,CAAiBO,QAAzC,EAAmD,IAAnD;EACD;;EAEDC,EAAAA,OAAO,GAAG;EACRH,IAAAA,wBAAI,CAACI,MAAL,CAAY,KAAKL,QAAjB,EAA2B,KAAKJ,WAAL,CAAiBO,QAA5C;EACA,SAAKH,QAAL,GAAgB,IAAhB;EACD;EAED;;;EAEkB,SAAXM,WAAW,CAACT,OAAD,EAAU;EAC1B,WAAOI,wBAAI,CAACM,GAAL,CAASV,OAAT,EAAkB,KAAKM,QAAvB,CAAP;EACD;;EAEiB,aAAPT,OAAO,GAAG;EACnB,WAAOA,OAAP;EACD;;EAzBiB;;;;;;;;"} {"version":3,"file":"base-component.js","sources":["../src/base-component.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0): base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Data from './dom/data'\nimport EventHandler from './dom/event-handler'\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst VERSION = '5.0.0'\n\nclass BaseComponent {\n constructor(element) {\n element = typeof element === 'string' ? document.querySelector(element) : element\n\n if (!element) {\n return\n }\n\n this._element = element\n Data.set(this._element, this.constructor.DATA_KEY, this)\n }\n\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY)\n EventHandler.off(this._element, `.${this.constructor.DATA_KEY}`)\n this._element = null\n }\n\n /** Static */\n\n static getInstance(element) {\n return Data.get(element, this.DATA_KEY)\n }\n\n static get VERSION() {\n return VERSION\n }\n}\n\nexport default BaseComponent\n"],"names":["VERSION","BaseComponent","constructor","element","document","querySelector","_element","Data","set","DATA_KEY","dispose","remove","EventHandler","off","getInstance","get"],"mappings":";;;;;;;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;EAKA;EACA;EACA;EACA;EACA;;EAEA,MAAMA,OAAO,GAAG,OAAhB;;EAEA,MAAMC,aAAN,CAAoB;EAClBC,EAAAA,WAAW,CAACC,OAAD,EAAU;EACnBA,IAAAA,OAAO,GAAG,OAAOA,OAAP,KAAmB,QAAnB,GAA8BC,QAAQ,CAACC,aAAT,CAAuBF,OAAvB,CAA9B,GAAgEA,OAA1E;;EAEA,QAAI,CAACA,OAAL,EAAc;EACZ;EACD;;EAED,SAAKG,QAAL,GAAgBH,OAAhB;EACAI,IAAAA,wBAAI,CAACC,GAAL,CAAS,KAAKF,QAAd,EAAwB,KAAKJ,WAAL,CAAiBO,QAAzC,EAAmD,IAAnD;EACD;;EAEDC,EAAAA,OAAO,GAAG;EACRH,IAAAA,wBAAI,CAACI,MAAL,CAAY,KAAKL,QAAjB,EAA2B,KAAKJ,WAAL,CAAiBO,QAA5C;EACAG,IAAAA,gCAAY,CAACC,GAAb,CAAiB,KAAKP,QAAtB,EAAiC,IAAG,KAAKJ,WAAL,CAAiBO,QAAS,EAA9D;EACA,SAAKH,QAAL,GAAgB,IAAhB;EACD;EAED;;;EAEkB,SAAXQ,WAAW,CAACX,OAAD,EAAU;EAC1B,WAAOI,wBAAI,CAACQ,GAAL,CAASZ,OAAT,EAAkB,KAAKM,QAAvB,CAAP;EACD;;EAEiB,aAAPT,OAAO,GAAG;EACnB,WAAOA,OAAP;EACD;;EA1BiB;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap button.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap button.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -27,7 +27,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -70,7 +70,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): button.js * Bootstrap (v5.0.0): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap carousel.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap carousel.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -43,7 +43,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -75,7 +75,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -142,9 +142,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -210,7 +208,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): carousel.js * Bootstrap (v5.0.0): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -401,7 +399,6 @@
} }
dispose() { dispose() {
EventHandler__default['default'].off(this._element, EVENT_KEY);
this._items = null; this._items = null;
this._config = null; this._config = null;
this._interval = null; this._interval = null;
@ -537,11 +534,11 @@
if (event.key === ARROW_LEFT_KEY) { if (event.key === ARROW_LEFT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_LEFT); this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) { } else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_RIGHT); this._slide(DIRECTION_LEFT);
} }
} }
@ -723,10 +720,10 @@
} }
if (isRTL()) { if (isRTL()) {
return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT; return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
} }
return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV; return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
} }
_orderToDirection(order) { _orderToDirection(order) {
@ -735,10 +732,10 @@
} }
if (isRTL()) { if (isRTL()) {
return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT; return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
} }
return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT; return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
} // Static } // Static
static carouselInterface(element, config) { static carouselInterface(element, config) {

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap collapse.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap collapse.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -43,7 +43,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -75,7 +75,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -152,9 +152,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -200,7 +198,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): collapse.js * Bootstrap (v5.0.0): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap data.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap data.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -15,7 +15,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/data.js * Bootstrap (v5.0.0): dom/data.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1 +1 @@
{"version":3,"file":"data.js","sources":["../../src/dom/data.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0-beta3): 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.0.0): 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;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap event-handler.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap event-handler.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -15,7 +15,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -32,7 +32,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/event-handler.js * Bootstrap (v5.0.0): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -52,6 +52,7 @@
mouseenter: 'mouseover', mouseenter: 'mouseover',
mouseleave: 'mouseout', mouseleave: 'mouseout',
}; };
const customEventsRegex = /^(mouseenter|mouseleave)/i;
const nativeEvents = new Set([ const nativeEvents = new Set([
'click', 'click',
'dblclick', 'dblclick',
@ -140,7 +141,7 @@
if (handler.oneOff) { if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring // eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, fn); EventHandler.off(element, event.type, selector, fn);
} }
return fn.apply(target, [event]); return fn.apply(target, [event]);
@ -168,15 +169,8 @@
function normalizeParams(originalTypeEvent, handler, delegationFn) { function normalizeParams(originalTypeEvent, handler, delegationFn) {
const delegation = typeof handler === 'string'; const delegation = typeof handler === 'string';
const originalHandler = delegation ? delegationFn : handler; // allow to get the native events from namespaced events ('click.bs.button' --> 'click') const originalHandler = delegation ? delegationFn : handler;
let typeEvent = getTypeEvent(originalTypeEvent);
let typeEvent = originalTypeEvent.replace(stripNameRegex, '');
const custom = customEvents[typeEvent];
if (custom) {
typeEvent = custom;
}
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);
if (!isNative) { if (!isNative) {
@ -194,6 +188,27 @@
if (!handler) { if (!handler) {
handler = delegationFn; handler = delegationFn;
delegationFn = null; delegationFn = null;
} // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
if (customEventsRegex.test(originalTypeEvent)) {
const wrapFn = (fn) => {
return function (event) {
if (
!event.relatedTarget ||
(event.relatedTarget !== event.delegateTarget &&
!event.delegateTarget.contains(event.relatedTarget))
) {
return fn.call(this, event);
}
};
};
if (delegationFn) {
delegationFn = wrapFn(delegationFn);
} else {
handler = wrapFn(handler);
}
} }
const [delegation, originalHandler, typeEvent] = normalizeParams( const [delegation, originalHandler, typeEvent] = normalizeParams(
@ -243,6 +258,12 @@
}); });
} }
function getTypeEvent(event) {
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
event = event.replace(stripNameRegex, '');
return customEvents[event] || event;
}
const EventHandler = { const EventHandler = {
on(element, event, handler, delegationFn) { on(element, event, handler, delegationFn) {
addHandler(element, event, handler, delegationFn, false); addHandler(element, event, handler, delegationFn, false);
@ -305,7 +326,7 @@
} }
const $ = getjQuery(); const $ = getjQuery();
const typeEvent = event.replace(stripNameRegex, ''); const typeEvent = getTypeEvent(event);
const inNamespace = event !== typeEvent; const inNamespace = event !== typeEvent;
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);
let jQueryEvent; let jQueryEvent;

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap manipulator.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap manipulator.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -15,7 +15,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/manipulator.js * Bootstrap (v5.0.0): dom/manipulator.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1 +1 @@
{"version":3,"file":"manipulator.js","sources":["../../src/dom/manipulator.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0-beta3): 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.0.0): 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;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap selector-engine.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap selector-engine.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -15,7 +15,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/selector-engine.js * Bootstrap (v5.0.0): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1 +1 @@
{"version":3,"file":"selector-engine.js","sources":["../../src/dom/selector-engine.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0-beta3): dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NODE_TEXT = 3\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector)\n },\n\n children(element, selector) {\n return [].concat(...element.children)\n .filter(child => child.matches(selector))\n },\n\n parents(element, selector) {\n const parents = []\n\n let ancestor = element.parentNode\n\n while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n if (ancestor.matches(selector)) {\n parents.push(ancestor)\n }\n\n ancestor = ancestor.parentNode\n }\n\n return parents\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous]\n }\n\n previous = previous.previousElementSibling\n }\n\n return []\n },\n\n next(element, selector) {\n let next = element.nextElementSibling\n\n while (next) {\n if (next.matches(selector)) {\n return [next]\n }\n\n next = next.nextElementSibling\n }\n\n return []\n }\n}\n\nexport default SelectorEngine\n"],"names":["NODE_TEXT","SelectorEngine","find","selector","element","document","documentElement","concat","Element","prototype","querySelectorAll","call","findOne","querySelector","children","filter","child","matches","parents","ancestor","parentNode","nodeType","Node","ELEMENT_NODE","push","prev","previous","previousElementSibling","next","nextElementSibling"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EAEA,MAAMA,SAAS,GAAG,CAAlB;QAEMC,cAAc,GAAG;EACrBC,EAAAA,IAAI,CAACC,QAAD,EAAWC,OAAO,GAAGC,QAAQ,CAACC,eAA9B,EAA+C;EACjD,WAAO,GAAGC,MAAH,CAAU,GAAGC,OAAO,CAACC,SAAR,CAAkBC,gBAAlB,CAAmCC,IAAnC,CAAwCP,OAAxC,EAAiDD,QAAjD,CAAb,CAAP;EACD,GAHoB;;EAKrBS,EAAAA,OAAO,CAACT,QAAD,EAAWC,OAAO,GAAGC,QAAQ,CAACC,eAA9B,EAA+C;EACpD,WAAOE,OAAO,CAACC,SAAR,CAAkBI,aAAlB,CAAgCF,IAAhC,CAAqCP,OAArC,EAA8CD,QAA9C,CAAP;EACD,GAPoB;;EASrBW,EAAAA,QAAQ,CAACV,OAAD,EAAUD,QAAV,EAAoB;EAC1B,WAAO,GAAGI,MAAH,CAAU,GAAGH,OAAO,CAACU,QAArB,EACJC,MADI,CACGC,KAAK,IAAIA,KAAK,CAACC,OAAN,CAAcd,QAAd,CADZ,CAAP;EAED,GAZoB;;EAcrBe,EAAAA,OAAO,CAACd,OAAD,EAAUD,QAAV,EAAoB;EACzB,UAAMe,OAAO,GAAG,EAAhB;EAEA,QAAIC,QAAQ,GAAGf,OAAO,CAACgB,UAAvB;;EAEA,WAAOD,QAAQ,IAAIA,QAAQ,CAACE,QAAT,KAAsBC,IAAI,CAACC,YAAvC,IAAuDJ,QAAQ,CAACE,QAAT,KAAsBrB,SAApF,EAA+F;EAC7F,UAAImB,QAAQ,CAACF,OAAT,CAAiBd,QAAjB,CAAJ,EAAgC;EAC9Be,QAAAA,OAAO,CAACM,IAAR,CAAaL,QAAb;EACD;;EAEDA,MAAAA,QAAQ,GAAGA,QAAQ,CAACC,UAApB;EACD;;EAED,WAAOF,OAAP;EACD,GA5BoB;;EA8BrBO,EAAAA,IAAI,CAACrB,OAAD,EAAUD,QAAV,EAAoB;EACtB,QAAIuB,QAAQ,GAAGtB,OAAO,CAACuB,sBAAvB;;EAEA,WAAOD,QAAP,EAAiB;EACf,UAAIA,QAAQ,CAACT,OAAT,CAAiBd,QAAjB,CAAJ,EAAgC;EAC9B,eAAO,CAACuB,QAAD,CAAP;EACD;;EAEDA,MAAAA,QAAQ,GAAGA,QAAQ,CAACC,sBAApB;EACD;;EAED,WAAO,EAAP;EACD,GA1CoB;;EA4CrBC,EAAAA,IAAI,CAACxB,OAAD,EAAUD,QAAV,EAAoB;EACtB,QAAIyB,IAAI,GAAGxB,OAAO,CAACyB,kBAAnB;;EAEA,WAAOD,IAAP,EAAa;EACX,UAAIA,IAAI,CAACX,OAAL,CAAad,QAAb,CAAJ,EAA4B;EAC1B,eAAO,CAACyB,IAAD,CAAP;EACD;;EAEDA,MAAAA,IAAI,GAAGA,IAAI,CAACC,kBAAZ;EACD;;EAED,WAAO,EAAP;EACD;;EAxDoB;;;;;;;;"} {"version":3,"file":"selector-engine.js","sources":["../../src/dom/selector-engine.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.0.0): dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * ------------------------------------------------------------------------\n * Constants\n * ------------------------------------------------------------------------\n */\n\nconst NODE_TEXT = 3\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector))\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector)\n },\n\n children(element, selector) {\n return [].concat(...element.children)\n .filter(child => child.matches(selector))\n },\n\n parents(element, selector) {\n const parents = []\n\n let ancestor = element.parentNode\n\n while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {\n if (ancestor.matches(selector)) {\n parents.push(ancestor)\n }\n\n ancestor = ancestor.parentNode\n }\n\n return parents\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous]\n }\n\n previous = previous.previousElementSibling\n }\n\n return []\n },\n\n next(element, selector) {\n let next = element.nextElementSibling\n\n while (next) {\n if (next.matches(selector)) {\n return [next]\n }\n\n next = next.nextElementSibling\n }\n\n return []\n }\n}\n\nexport default SelectorEngine\n"],"names":["NODE_TEXT","SelectorEngine","find","selector","element","document","documentElement","concat","Element","prototype","querySelectorAll","call","findOne","querySelector","children","filter","child","matches","parents","ancestor","parentNode","nodeType","Node","ELEMENT_NODE","push","prev","previous","previousElementSibling","next","nextElementSibling"],"mappings":";;;;;;;;;;;EAAA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EAEA,MAAMA,SAAS,GAAG,CAAlB;QAEMC,cAAc,GAAG;EACrBC,EAAAA,IAAI,CAACC,QAAD,EAAWC,OAAO,GAAGC,QAAQ,CAACC,eAA9B,EAA+C;EACjD,WAAO,GAAGC,MAAH,CAAU,GAAGC,OAAO,CAACC,SAAR,CAAkBC,gBAAlB,CAAmCC,IAAnC,CAAwCP,OAAxC,EAAiDD,QAAjD,CAAb,CAAP;EACD,GAHoB;;EAKrBS,EAAAA,OAAO,CAACT,QAAD,EAAWC,OAAO,GAAGC,QAAQ,CAACC,eAA9B,EAA+C;EACpD,WAAOE,OAAO,CAACC,SAAR,CAAkBI,aAAlB,CAAgCF,IAAhC,CAAqCP,OAArC,EAA8CD,QAA9C,CAAP;EACD,GAPoB;;EASrBW,EAAAA,QAAQ,CAACV,OAAD,EAAUD,QAAV,EAAoB;EAC1B,WAAO,GAAGI,MAAH,CAAU,GAAGH,OAAO,CAACU,QAArB,EACJC,MADI,CACGC,KAAK,IAAIA,KAAK,CAACC,OAAN,CAAcd,QAAd,CADZ,CAAP;EAED,GAZoB;;EAcrBe,EAAAA,OAAO,CAACd,OAAD,EAAUD,QAAV,EAAoB;EACzB,UAAMe,OAAO,GAAG,EAAhB;EAEA,QAAIC,QAAQ,GAAGf,OAAO,CAACgB,UAAvB;;EAEA,WAAOD,QAAQ,IAAIA,QAAQ,CAACE,QAAT,KAAsBC,IAAI,CAACC,YAAvC,IAAuDJ,QAAQ,CAACE,QAAT,KAAsBrB,SAApF,EAA+F;EAC7F,UAAImB,QAAQ,CAACF,OAAT,CAAiBd,QAAjB,CAAJ,EAAgC;EAC9Be,QAAAA,OAAO,CAACM,IAAR,CAAaL,QAAb;EACD;;EAEDA,MAAAA,QAAQ,GAAGA,QAAQ,CAACC,UAApB;EACD;;EAED,WAAOF,OAAP;EACD,GA5BoB;;EA8BrBO,EAAAA,IAAI,CAACrB,OAAD,EAAUD,QAAV,EAAoB;EACtB,QAAIuB,QAAQ,GAAGtB,OAAO,CAACuB,sBAAvB;;EAEA,WAAOD,QAAP,EAAiB;EACf,UAAIA,QAAQ,CAACT,OAAT,CAAiBd,QAAjB,CAAJ,EAAgC;EAC9B,eAAO,CAACuB,QAAD,CAAP;EACD;;EAEDA,MAAAA,QAAQ,GAAGA,QAAQ,CAACC,sBAApB;EACD;;EAED,WAAO,EAAP;EACD,GA1CoB;;EA4CrBC,EAAAA,IAAI,CAACxB,OAAD,EAAUD,QAAV,EAAoB;EACtB,QAAIyB,IAAI,GAAGxB,OAAO,CAACyB,kBAAnB;;EAEA,WAAOD,IAAP,EAAa;EACX,UAAIA,IAAI,CAACX,OAAL,CAAad,QAAb,CAAJ,EAA4B;EAC1B,eAAO,CAACyB,IAAD,CAAP;EACD;;EAEDA,MAAAA,IAAI,GAAGA,IAAI,CAACC,kBAAZ;EACD;;EAED,WAAO,EAAP;EACD;;EAxDoB;;;;;;;;"}

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap dropdown.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap dropdown.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -73,7 +73,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -103,7 +103,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -127,9 +127,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -153,7 +151,23 @@
return false; return false;
}; };
const noop = () => function () {}; 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 noop = () => {};
const getjQuery = () => { const getjQuery = () => {
const { jQuery } = window; const { jQuery } = window;
@ -195,7 +209,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dropdown.js * Bootstrap (v5.0.0): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -225,7 +239,6 @@
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_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_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`; const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_DISABLED = 'disabled';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_DROPUP = 'dropup'; const CLASS_NAME_DROPUP = 'dropup';
const CLASS_NAME_DROPEND = 'dropend'; const CLASS_NAME_DROPEND = 'dropend';
@ -247,6 +260,7 @@
reference: 'toggle', reference: 'toggle',
display: 'dynamic', display: 'dynamic',
popperConfig: null, popperConfig: null,
autoClose: true,
}; };
const DefaultType = { const DefaultType = {
offset: '(array|string|function)', offset: '(array|string|function)',
@ -254,6 +268,7 @@
reference: '(string|element|object)', reference: '(string|element|object)',
display: 'string', display: 'string',
popperConfig: '(null|object|function)', popperConfig: '(null|object|function)',
autoClose: '(boolean|string)',
}; };
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -285,15 +300,14 @@
} // Public } // Public
toggle() { toggle() {
if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) { if (isDisabled(this._element)) {
return; return;
} }
const isActive = this._element.classList.contains(CLASS_NAME_SHOW); const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
Dropdown.clearMenus();
if (isActive) { if (isActive) {
this.hide();
return; return;
} }
@ -301,11 +315,7 @@
} }
show() { show() {
if ( if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
@ -362,7 +372,7 @@
if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) { if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
[] []
.concat(...document.body.children) .concat(...document.body.children)
.forEach((elem) => EventHandler__default['default'].on(elem, 'mouseover', null, noop())); .forEach((elem) => EventHandler__default['default'].on(elem, 'mouseover', noop));
} }
this._element.focus(); this._element.focus();
@ -377,41 +387,18 @@
} }
hide() { hide() {
if ( if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
!this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
const relatedTarget = { const relatedTarget = {
relatedTarget: this._element, relatedTarget: this._element,
}; };
const hideEvent = EventHandler__default['default'].trigger(
this._element,
EVENT_HIDE,
relatedTarget
);
if (hideEvent.defaultPrevented) { this._completeHide(relatedTarget);
return;
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
Manipulator__default['default'].removeDataAttribute(this._menu, 'popper');
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN, relatedTarget);
} }
dispose() { dispose() {
EventHandler__default['default'].off(this._element, EVENT_KEY);
this._menu = null; this._menu = null;
if (this._popper) { if (this._popper) {
@ -438,6 +425,38 @@
}); });
} }
_completeHide(relatedTarget) {
const hideEvent = EventHandler__default['default'].trigger(
this._element,
EVENT_HIDE,
relatedTarget
);
if (hideEvent.defaultPrevented) {
return;
} // If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler__default['default'].off(elem, 'mouseover', noop));
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.remove(CLASS_NAME_SHOW);
this._element.classList.remove(CLASS_NAME_SHOW);
this._element.setAttribute('aria-expanded', 'false');
Manipulator__default['default'].removeDataAttribute(this._menu, 'popper');
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN, relatedTarget);
}
_getConfig(config) { _getConfig(config) {
config = { config = {
...this.constructor.Default, ...this.constructor.Default,
@ -536,6 +555,29 @@
? this._config.popperConfig(defaultBsPopperConfig) ? this._config.popperConfig(defaultBsPopperConfig)
: this._config.popperConfig), : this._config.popperConfig),
}; };
}
_selectMenuItem(event) {
const items = SelectorEngine__default['default']
.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();
} // Static } // Static
static dropdownInterface(element, config) { static dropdownInterface(element, config) {
@ -571,7 +613,7 @@
return; return;
} }
if (/input|select|textarea|form/i.test(event.target.tagName)) { if (/input|select|option|textarea|form/i.test(event.target.tagName)) {
return; return;
} }
} }
@ -580,68 +622,45 @@
for (let i = 0, len = toggles.length; i < len; i++) { for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data__default['default'].get(toggles[i], DATA_KEY); const context = Data__default['default'].get(toggles[i], DATA_KEY);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
continue;
}
const relatedTarget = { const relatedTarget = {
relatedTarget: toggles[i], relatedTarget: context._element,
}; };
if (event && event.type === 'click') {
relatedTarget.clickEvent = event;
}
if (!context) {
continue;
}
const dropdownMenu = context._menu;
if (!toggles[i].classList.contains(CLASS_NAME_SHOW)) {
continue;
}
if (event) { if (event) {
// Don't close the menu if the clicked element or one of its parents is the dropdown button const composedPath = event.composedPath();
if ([context._element].some((element) => event.composedPath().includes(element))) { const isMenuTarget = composedPath.includes(context._menu);
if (
composedPath.includes(context._element) ||
(context._config.autoClose === 'inside' && !isMenuTarget) ||
(context._config.autoClose === 'outside' && isMenuTarget)
) {
continue; continue;
} // Tab navigation through the dropdown menu shouldn't close the menu } // Tab navigation through the dropdown menu shouldn't close the menu
if ( if (
event.type === 'keyup' && event.type === 'keyup' &&
event.key === TAB_KEY && event.key === TAB_KEY &&
dropdownMenu.contains(event.target) context._menu.contains(event.target)
) { ) {
continue; continue;
} }
if (event.type === 'click') {
relatedTarget.clickEvent = event;
}
} }
const hideEvent = EventHandler__default['default'].trigger( context._completeHide(relatedTarget);
toggles[i],
EVENT_HIDE,
relatedTarget
);
if (hideEvent.defaultPrevented) {
continue;
} // If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) =>
EventHandler__default['default'].off(elem, 'mouseover', null, noop())
);
}
toggles[i].setAttribute('aria-expanded', 'false');
if (context._popper) {
context._popper.destroy();
}
dropdownMenu.classList.remove(CLASS_NAME_SHOW);
toggles[i].classList.remove(CLASS_NAME_SHOW);
Manipulator__default['default'].removeDataAttribute(dropdownMenu, 'popper');
EventHandler__default['default'].trigger(toggles[i], EVENT_HIDDEN, relatedTarget);
} }
} }
@ -668,30 +687,32 @@
return; return;
} }
event.preventDefault(); const isActive = this.classList.contains(CLASS_NAME_SHOW);
event.stopPropagation();
if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) { if (!isActive && event.key === ESCAPE_KEY) {
return; return;
} }
const parent = Dropdown.getParentFromElement(this); event.preventDefault();
const isActive = this.classList.contains(CLASS_NAME_SHOW); event.stopPropagation();
if (event.key === ESCAPE_KEY) { if (isDisabled(this)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
? this ? this
: SelectorEngine__default['default'].prev(this, SELECTOR_DATA_TOGGLE)[0]; : SelectorEngine__default['default'].prev(this, SELECTOR_DATA_TOGGLE)[0];
button.focus();
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus(); Dropdown.clearMenus();
return; return;
} }
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) { if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) getToggleButton().click();
? this
: SelectorEngine__default['default'].prev(this, SELECTOR_DATA_TOGGLE)[0];
button.click();
return; return;
} }
@ -700,26 +721,7 @@
return; return;
} }
const items = SelectorEngine__default['default'] Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
.find(SELECTOR_VISIBLE_ITEMS, parent)
.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();
} }
} }
/** /**

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,11 @@
/*! /*!
* Bootstrap modal.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap modal.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
(function (global, factory) { (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory( ? (module.exports = factory(
require('./dom/data.js'),
require('./dom/event-handler.js'), require('./dom/event-handler.js'),
require('./dom/manipulator.js'), require('./dom/manipulator.js'),
require('./dom/selector-engine.js'), require('./dom/selector-engine.js'),
@ -14,7 +13,6 @@
)) ))
: typeof define === 'function' && define.amd : typeof define === 'function' && define.amd
? define([ ? define([
'./dom/data',
'./dom/event-handler', './dom/event-handler',
'./dom/manipulator', './dom/manipulator',
'./dom/selector-engine', './dom/selector-engine',
@ -22,20 +20,18 @@
], factory) ], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.Modal = factory( (global.Modal = factory(
global.Data,
global.EventHandler, global.EventHandler,
global.Manipulator, global.Manipulator,
global.SelectorEngine, global.SelectorEngine,
global.Base global.Base
))); )));
})(this, function (Data, EventHandler, Manipulator, SelectorEngine, BaseComponent) { })(this, function (EventHandler, Manipulator, SelectorEngine, BaseComponent) {
'use strict'; 'use strict';
function _interopDefaultLegacy(e) { function _interopDefaultLegacy(e) {
return e && typeof e === 'object' && 'default' in e ? e : { default: e }; return e && typeof e === 'object' && 'default' in e ? e : { default: e };
} }
var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler); var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator); var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine); var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine);
@ -43,7 +39,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -75,7 +71,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -142,9 +138,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -208,9 +202,221 @@
}); });
}; };
const execute = (callback) => {
if (typeof callback === 'function') {
callback();
}
};
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): modal.js * Bootstrap (v5.0.0): 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 = () => {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
const documentWidth = document.documentElement.clientWidth;
return Math.abs(window.innerWidth - documentWidth);
};
const hide = (width = getWidth()) => {
_disableOverFlow(); // give padding to element to balances the hidden scrollbar width
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
_setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - width
);
};
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator__default['default'].setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
};
const _setElementAttributes = (selector, styleProp, callback) => {
const scrollbarWidth = getWidth();
SelectorEngine__default['default'].find(selector).forEach((element) => {
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
return;
}
const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
});
};
const reset = () => {
_resetElementAttributes('body', 'overflow');
_resetElementAttributes('body', 'paddingRight');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
};
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine__default['default'].find(selector).forEach((element) => {
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp);
} else {
Manipulator__default['default'].removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
};
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): util/backdrop.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Default$1 = {
isVisible: true,
// if false, we use the backdrop helper without adding any element to the dom
isAnimated: false,
rootElement: document.body,
// give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType$1 = {
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
clickCallback: '(function|null)',
};
const NAME$1 = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE$1 = 'fade';
const CLASS_NAME_SHOW$1 = 'show';
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$1}`;
class Backdrop {
constructor(config) {
this._config = this._getConfig(config);
this._isAppended = false;
this._element = null;
}
show(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._append();
if (this._config.isAnimated) {
reflow(this._getElement());
}
this._getElement().classList.add(CLASS_NAME_SHOW$1);
this._emulateAnimation(() => {
execute(callback);
});
}
hide(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._getElement().classList.remove(CLASS_NAME_SHOW$1);
this._emulateAnimation(() => {
this.dispose();
execute(callback);
});
} // Private
_getElement() {
if (!this._element) {
const backdrop = document.createElement('div');
backdrop.className = CLASS_NAME_BACKDROP;
if (this._config.isAnimated) {
backdrop.classList.add(CLASS_NAME_FADE$1);
}
this._element = backdrop;
}
return this._element;
}
_getConfig(config) {
config = { ...Default$1, ...(typeof config === 'object' ? config : {}) };
typeCheckConfig(NAME$1, config, DefaultType$1);
return config;
}
_append() {
if (this._isAppended) {
return;
}
this._config.rootElement.appendChild(this._getElement());
EventHandler__default['default'].on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
});
this._isAppended = true;
}
dispose() {
if (!this._isAppended) {
return;
}
EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler__default['default'].one(this._getElement(), 'transitionend', () =>
execute(callback)
);
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -247,8 +453,6 @@
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`; const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`;
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`; const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_OPEN = 'modal-open'; const CLASS_NAME_OPEN = 'modal-open';
const CLASS_NAME_FADE = 'fade'; const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
@ -257,8 +461,6 @@
const SELECTOR_MODAL_BODY = '.modal-body'; const SELECTOR_MODAL_BODY = '.modal-body';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]';
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]'; const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
* Class Definition * Class Definition
@ -270,12 +472,10 @@
super(element); super(element);
this._config = this._getConfig(config); 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 = null; this._backdrop = this._initializeBackDrop();
this._isShown = false; this._isShown = false;
this._isBodyOverflowing = false;
this._ignoreBackdropClick = false; this._ignoreBackdropClick = false;
this._isTransitioning = false; this._isTransitioning = false;
this._scrollbarWidth = 0;
} // Getters } // Getters
static get Default() { static get Default() {
@ -308,10 +508,8 @@
} }
this._isShown = true; this._isShown = true;
hide();
this._checkScrollbar(); document.body.classList.add(CLASS_NAME_OPEN);
this._setScrollbar();
this._adjustDialog(); this._adjustDialog();
@ -382,7 +580,7 @@
} }
dispose() { dispose() {
[window, this._element, this._dialog].forEach((htmlElement) => [window, this._dialog].forEach((htmlElement) =>
EventHandler__default['default'].off(htmlElement, EVENT_KEY) EventHandler__default['default'].off(htmlElement, EVENT_KEY)
); );
super.dispose(); super.dispose();
@ -395,20 +593,33 @@
EventHandler__default['default'].off(document, EVENT_FOCUSIN); EventHandler__default['default'].off(document, EVENT_FOCUSIN);
this._config = null; this._config = null;
this._dialog = null; this._dialog = null;
this._backdrop.dispose();
this._backdrop = null; this._backdrop = null;
this._isShown = null; this._isShown = null;
this._isBodyOverflowing = null;
this._ignoreBackdropClick = null; this._ignoreBackdropClick = null;
this._isTransitioning = null; this._isTransitioning = null;
this._scrollbarWidth = null;
} }
handleUpdate() { handleUpdate() {
this._adjustDialog(); this._adjustDialog();
} // Private } // Private
_initializeBackDrop() {
return new Backdrop({
isVisible: Boolean(this._config.backdrop),
// 'static' option will be translated to true, and booleans will keep their value
isAnimated: this._isAnimated(),
});
}
_getConfig(config) { _getConfig(config) {
config = { ...Default, ...config }; config = {
...Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...config,
};
typeCheckConfig(NAME, config, DefaultType); typeCheckConfig(NAME, config, DefaultType);
return config; return config;
} }
@ -518,85 +729,35 @@
this._isTransitioning = false; this._isTransitioning = false;
this._showBackdrop(() => { this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN); document.body.classList.remove(CLASS_NAME_OPEN);
this._resetAdjustments(); this._resetAdjustments();
this._resetScrollbar(); reset();
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN); EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
}); });
} }
_removeBackdrop() {
this._backdrop.parentNode.removeChild(this._backdrop);
this._backdrop = null;
}
_showBackdrop(callback) { _showBackdrop(callback) {
const isAnimated = this._isAnimated(); EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
if (this._isShown && this._config.backdrop) { this._ignoreBackdropClick = false;
this._backdrop = document.createElement('div');
this._backdrop.className = CLASS_NAME_BACKDROP;
if (isAnimated) {
this._backdrop.classList.add(CLASS_NAME_FADE);
}
document.body.appendChild(this._backdrop);
EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false;
return;
}
if (event.target !== event.currentTarget) {
return;
}
if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
} else {
this.hide();
}
});
if (isAnimated) {
reflow(this._backdrop);
}
this._backdrop.classList.add(CLASS_NAME_SHOW);
if (!isAnimated) {
callback();
return; return;
} }
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); if (event.target !== event.currentTarget) {
EventHandler__default['default'].one(this._backdrop, 'transitionend', callback); return;
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else if (!this._isShown && this._backdrop) {
this._backdrop.classList.remove(CLASS_NAME_SHOW);
const callbackRemove = () => {
this._removeBackdrop();
callback();
};
if (isAnimated) {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop);
EventHandler__default['default'].one(this._backdrop, 'transitionend', callbackRemove);
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else {
callbackRemove();
} }
} else {
callback(); if (this._config.backdrop === true) {
} this.hide();
} else if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
}
});
this._backdrop.show(callback);
} }
_isAnimated() { _isAnimated() {
@ -642,124 +803,43 @@
_adjustDialog() { _adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if ( if (
(!this._isBodyOverflowing && isModalOverflowing && !isRTL()) || (!isBodyOverflowing && isModalOverflowing && !isRTL()) ||
(this._isBodyOverflowing && !isModalOverflowing && isRTL()) (isBodyOverflowing && !isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingLeft = `${this._scrollbarWidth}px`; this._element.style.paddingLeft = `${scrollbarWidth}px`;
} }
if ( if (
(this._isBodyOverflowing && !isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && !isRTL()) ||
(!this._isBodyOverflowing && isModalOverflowing && isRTL()) (!isBodyOverflowing && isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingRight = `${this._scrollbarWidth}px`; this._element.style.paddingRight = `${scrollbarWidth}px`;
} }
} }
_resetAdjustments() { _resetAdjustments() {
this._element.style.paddingLeft = ''; this._element.style.paddingLeft = '';
this._element.style.paddingRight = ''; this._element.style.paddingRight = '';
}
_checkScrollbar() {
const rect = document.body.getBoundingClientRect();
this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
this._scrollbarWidth = this._getScrollbarWidth();
}
_setScrollbar() {
if (this._isBodyOverflowing) {
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
this._setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - this._scrollbarWidth
);
this._setElementAttributes(
'body',
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
}
document.body.classList.add(CLASS_NAME_OPEN);
}
_setElementAttributes(selector, styleProp, callback) {
SelectorEngine__default['default'].find(selector).forEach((element) => {
if (
element !== document.body &&
window.innerWidth > element.clientWidth + this._scrollbarWidth
) {
return;
}
const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px';
});
}
_resetScrollbar() {
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
this._resetElementAttributes('body', 'paddingRight');
}
_resetElementAttributes(selector, styleProp) {
SelectorEngine__default['default'].find(selector).forEach((element) => {
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) {
element.style[styleProp] = '';
} else {
Manipulator__default['default'].removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
}
_getScrollbarWidth() {
// thx d.walsh
const scrollDiv = document.createElement('div');
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
} // Static } // Static
static jQueryInterface(config, relatedTarget) { static jQueryInterface(config, relatedTarget) {
return this.each(function () { return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY); const data =
const _config = { Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
...Default,
...Manipulator__default['default'].getDataAttributes(this),
...(typeof config === 'object' && config ? config : {}),
};
if (!data) { if (typeof config !== 'string') {
data = new Modal(this, _config); return;
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config](relatedTarget);
} }
data[config](relatedTarget);
}); });
} }
} }
@ -776,7 +856,7 @@
function (event) { function (event) {
const target = getElementFromSelector(this); const target = getElementFromSelector(this);
if (this.tagName === 'A' || this.tagName === 'AREA') { if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault(); event.preventDefault();
} }
@ -792,16 +872,7 @@
} }
}); });
}); });
let data = Data__default['default'].get(target, DATA_KEY); const data = Modal.getInstance(target) || new Modal(target);
if (!data) {
const config = {
...Manipulator__default['default'].getDataAttributes(target),
...Manipulator__default['default'].getDataAttributes(this),
};
data = new Modal(target, config);
}
data.toggle(this); data.toggle(this);
} }
); );

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap offcanvas.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap offcanvas.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -43,11 +43,12 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
const MILLISECONDS_MULTIPLIER = 1000; const MILLISECONDS_MULTIPLIER = 1000;
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
const toType = (obj) => { const toType = (obj) => {
if (obj === null || obj === undefined) { if (obj === null || obj === undefined) {
@ -74,7 +75,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -83,16 +84,6 @@
return selector; return selector;
}; };
const getSelectorFromElement = (element) => {
const selector = getSelector(element);
if (selector) {
return document.querySelector(selector) ? selector : null;
}
return null;
};
const getElementFromSelector = (element) => { const getElementFromSelector = (element) => {
const selector = getSelector(element); const selector = getSelector(element);
return selector ? document.querySelector(selector) : null; return selector ? document.querySelector(selector) : null;
@ -119,8 +110,30 @@
); );
}; };
const triggerTransitionEnd = (element) => {
element.dispatchEvent(new Event(TRANSITION_END));
};
const isElement = (obj) => (obj[0] || obj).nodeType; const isElement = (obj) => (obj[0] || obj).nodeType;
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) => { const typeCheckConfig = (componentName, config, configTypes) => {
Object.keys(configTypes).forEach((property) => { Object.keys(configTypes).forEach((property) => {
const expectedTypes = configTypes[property]; const expectedTypes = configTypes[property];
@ -129,9 +142,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -171,6 +182,8 @@
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
}; };
const reflow = (element) => element.offsetHeight;
const getjQuery = () => { const getjQuery = () => {
const { jQuery } = window; const { jQuery } = window;
@ -207,13 +220,19 @@
}); });
}; };
const execute = (callback) => {
if (typeof callback === 'function') {
callback();
}
};
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/scrollBar.js * Bootstrap (v5.0.0): util/scrollBar.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed'; const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top'; const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => { const getWidth = () => {
@ -223,7 +242,9 @@
}; };
const hide = (width = getWidth()) => { const hide = (width = getWidth()) => {
document.body.style.overflow = 'hidden'; _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( _setElementAttributes(
SELECTOR_FIXED_CONTENT, SELECTOR_FIXED_CONTENT,
@ -236,8 +257,16 @@
'marginRight', 'marginRight',
(calculatedValue) => calculatedValue - width (calculatedValue) => calculatedValue - width
); );
};
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator__default['default'].setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
}; };
const _setElementAttributes = (selector, styleProp, callback) => { const _setElementAttributes = (selector, styleProp, callback) => {
@ -250,25 +279,25 @@
const actualValue = element.style[styleProp]; const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp]; const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue); Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px'; element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
}); });
}; };
const reset = () => { const reset = () => {
document.body.style.overflow = 'auto'; _resetElementAttributes('body', 'overflow');
_resetElementAttributes('body', 'paddingRight');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight'); _resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight'); _resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
_resetElementAttributes('body', 'paddingRight');
}; };
const _resetElementAttributes = (selector, styleProp) => { const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine__default['default'].find(selector).forEach((element) => { SelectorEngine__default['default'].find(selector).forEach((element) => {
const value = Manipulator__default['default'].getDataAttribute(element, styleProp); const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) { if (typeof value === 'undefined') {
element.style.removeProperty(styleProp); element.style.removeProperty(styleProp);
} else { } else {
Manipulator__default['default'].removeDataAttribute(element, styleProp); Manipulator__default['default'].removeDataAttribute(element, styleProp);
@ -279,7 +308,133 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): offcanvas.js * Bootstrap (v5.0.0): util/backdrop.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Default$1 = {
isVisible: true,
// if false, we use the backdrop helper without adding any element to the dom
isAnimated: false,
rootElement: document.body,
// give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType$1 = {
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
clickCallback: '(function|null)',
};
const NAME$1 = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW$1 = 'show';
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$1}`;
class Backdrop {
constructor(config) {
this._config = this._getConfig(config);
this._isAppended = false;
this._element = null;
}
show(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._append();
if (this._config.isAnimated) {
reflow(this._getElement());
}
this._getElement().classList.add(CLASS_NAME_SHOW$1);
this._emulateAnimation(() => {
execute(callback);
});
}
hide(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._getElement().classList.remove(CLASS_NAME_SHOW$1);
this._emulateAnimation(() => {
this.dispose();
execute(callback);
});
} // Private
_getElement() {
if (!this._element) {
const backdrop = document.createElement('div');
backdrop.className = CLASS_NAME_BACKDROP;
if (this._config.isAnimated) {
backdrop.classList.add(CLASS_NAME_FADE);
}
this._element = backdrop;
}
return this._element;
}
_getConfig(config) {
config = { ...Default$1, ...(typeof config === 'object' ? config : {}) };
typeCheckConfig(NAME$1, config, DefaultType$1);
return config;
}
_append() {
if (this._isAppended) {
return;
}
this._config.rootElement.appendChild(this._getElement());
EventHandler__default['default'].on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
});
this._isAppended = true;
}
dispose() {
if (!this._isAppended) {
return;
}
EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler__default['default'].one(this._getElement(), 'transitionend', () =>
execute(callback)
);
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
}
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -305,11 +460,8 @@
keyboard: 'boolean', keyboard: 'boolean',
scroll: 'boolean', scroll: 'boolean',
}; };
const CLASS_NAME_BACKDROP_BODY = 'offcanvas-backdrop';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_TOGGLING = 'offcanvas-toggling';
const OPEN_SELECTOR = '.offcanvas.show'; const OPEN_SELECTOR = '.offcanvas.show';
const ACTIVE_SELECTOR = `${OPEN_SELECTOR}, .${CLASS_NAME_TOGGLING}`;
const EVENT_SHOW = `show${EVENT_KEY}`; const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`; const EVENT_SHOWN = `shown${EVENT_KEY}`;
const EVENT_HIDE = `hide${EVENT_KEY}`; const EVENT_HIDE = `hide${EVENT_KEY}`;
@ -317,6 +469,7 @@
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_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_DISMISS = '[data-bs-dismiss="offcanvas"]';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
/** /**
@ -330,6 +483,7 @@
super(element); super(element);
this._config = this._getConfig(config); this._config = this._getConfig(config);
this._isShown = false; this._isShown = false;
this._backdrop = this._initializeBackDrop();
this._addEventListeners(); this._addEventListeners();
} // Getters } // Getters
@ -362,15 +516,13 @@
this._isShown = true; this._isShown = true;
this._element.style.visibility = 'visible'; this._element.style.visibility = 'visible';
if (this._config.backdrop) { this._backdrop.show();
document.body.classList.add(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
hide(); hide();
}
this._element.classList.add(CLASS_NAME_TOGGLING); this._enforceFocusOnElement(this._element);
}
this._element.removeAttribute('aria-hidden'); this._element.removeAttribute('aria-hidden');
@ -381,16 +533,14 @@
this._element.classList.add(CLASS_NAME_SHOW); this._element.classList.add(CLASS_NAME_SHOW);
const completeCallBack = () => { const completeCallBack = () => {
this._element.classList.remove(CLASS_NAME_TOGGLING);
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, { EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, {
relatedTarget, relatedTarget,
}); });
this._enforceFocusOnElement(this._element);
}; };
setTimeout(completeCallBack, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler__default['default'].one(this._element, 'transitionend', completeCallBack);
emulateTransitionEnd(this._element, transitionDuration);
} }
hide() { hide() {
@ -404,8 +554,6 @@
return; return;
} }
this._element.classList.add(CLASS_NAME_TOGGLING);
EventHandler__default['default'].off(document, EVENT_FOCUSIN); EventHandler__default['default'].off(document, EVENT_FOCUSIN);
this._element.blur(); this._element.blur();
@ -414,6 +562,8 @@
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
this._backdrop.hide();
const completeCallback = () => { const completeCallback = () => {
this._element.setAttribute('aria-hidden', true); this._element.setAttribute('aria-hidden', true);
@ -423,20 +573,25 @@
this._element.style.visibility = 'hidden'; this._element.style.visibility = 'hidden';
if (this._config.backdrop) {
document.body.classList.remove(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
reset(); reset();
} }
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN); EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
this._element.classList.remove(CLASS_NAME_TOGGLING);
}; };
setTimeout(completeCallback, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler__default['default'].one(this._element, 'transitionend', completeCallback);
emulateTransitionEnd(this._element, transitionDuration);
}
dispose() {
this._backdrop.dispose();
super.dispose();
EventHandler__default['default'].off(document, EVENT_FOCUSIN);
this._config = null;
this._backdrop = null;
} // Private } // Private
_getConfig(config) { _getConfig(config) {
@ -449,6 +604,15 @@
return config; return config;
} }
_initializeBackDrop() {
return new Backdrop({
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
clickCallback: () => this.hide(),
});
}
_enforceFocusOnElement(element) { _enforceFocusOnElement(element) {
EventHandler__default['default'].off(document, EVENT_FOCUSIN); // guard against infinite focus loop EventHandler__default['default'].off(document, EVENT_FOCUSIN); // guard against infinite focus loop
@ -471,20 +635,11 @@
SELECTOR_DATA_DISMISS, SELECTOR_DATA_DISMISS,
() => this.hide() () => this.hide()
); );
EventHandler__default['default'].on(document, 'keydown', (event) => { EventHandler__default['default'].on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.key === ESCAPE_KEY) { if (this._config.keyboard && event.key === ESCAPE_KEY) {
this.hide(); this.hide();
} }
}); });
EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, (event) => {
const target = SelectorEngine__default['default'].findOne(
getSelectorFromElement(event.target)
);
if (!this._element.contains(event.target) && target !== this._element) {
this.hide();
}
});
} // Static } // Static
static jQueryInterface(config) { static jQueryInterface(config) {
@ -533,10 +688,10 @@
} }
}); // avoid conflict when clicking a toggler of an offcanvas, while another is open }); // avoid conflict when clicking a toggler of an offcanvas, while another is open
const allReadyOpen = SelectorEngine__default['default'].findOne(ACTIVE_SELECTOR); const allReadyOpen = SelectorEngine__default['default'].findOne(OPEN_SELECTOR);
if (allReadyOpen && allReadyOpen !== target) { if (allReadyOpen && allReadyOpen !== target) {
return; Offcanvas.getInstance(allReadyOpen).hide();
} }
const data = Data__default['default'].get(target, DATA_KEY) || new Offcanvas(target); const data = Data__default['default'].get(target, DATA_KEY) || new Offcanvas(target);

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap popover.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap popover.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -27,7 +27,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -70,7 +70,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): popover.js * Bootstrap (v5.0.0): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,11 @@
/*! /*!
* Bootstrap scrollspy.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap scrollspy.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
(function (global, factory) { (function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory( ? (module.exports = factory(
require('./dom/data.js'),
require('./dom/event-handler.js'), require('./dom/event-handler.js'),
require('./dom/manipulator.js'), require('./dom/manipulator.js'),
require('./dom/selector-engine.js'), require('./dom/selector-engine.js'),
@ -14,7 +13,6 @@
)) ))
: typeof define === 'function' && define.amd : typeof define === 'function' && define.amd
? define([ ? define([
'./dom/data',
'./dom/event-handler', './dom/event-handler',
'./dom/manipulator', './dom/manipulator',
'./dom/selector-engine', './dom/selector-engine',
@ -22,20 +20,18 @@
], factory) ], factory)
: ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self),
(global.ScrollSpy = factory( (global.ScrollSpy = factory(
global.Data,
global.EventHandler, global.EventHandler,
global.Manipulator, global.Manipulator,
global.SelectorEngine, global.SelectorEngine,
global.Base global.Base
))); )));
})(this, function (Data, EventHandler, Manipulator, SelectorEngine, BaseComponent) { })(this, function (EventHandler, Manipulator, SelectorEngine, BaseComponent) {
'use strict'; 'use strict';
function _interopDefaultLegacy(e) { function _interopDefaultLegacy(e) {
return e && typeof e === 'object' && 'default' in e ? e : { default: e }; return e && typeof e === 'object' && 'default' in e ? e : { default: e };
} }
var Data__default = /*#__PURE__*/ _interopDefaultLegacy(Data);
var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler); var EventHandler__default = /*#__PURE__*/ _interopDefaultLegacy(EventHandler);
var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator); var Manipulator__default = /*#__PURE__*/ _interopDefaultLegacy(Manipulator);
var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine); var SelectorEngine__default = /*#__PURE__*/ _interopDefaultLegacy(SelectorEngine);
@ -43,7 +39,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -87,7 +83,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -116,9 +112,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -162,7 +156,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): scrollspy.js * Bootstrap (v5.0.0): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -281,7 +275,11 @@
} // Private } // Private
_getConfig(config) { _getConfig(config) {
config = { ...Default, ...(typeof config === 'object' && config ? config : {}) }; config = {
...Default,
...Manipulator__default['default'].getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {}),
};
if (typeof config.target !== 'string' && isElement(config.target)) { if (typeof config.target !== 'string' && isElement(config.target)) {
let { id } = config.target; let { id } = config.target;
@ -410,21 +408,19 @@
static jQueryInterface(config) { static jQueryInterface(config) {
return this.each(function () { return this.each(function () {
let data = Data__default['default'].get(this, DATA_KEY); const data =
ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
const _config = typeof config === 'object' && config; if (typeof config !== 'string') {
return;
if (!data) {
data = new ScrollSpy(this, _config);
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config]();
} }
data[config]();
}); });
} }
} }
@ -435,9 +431,7 @@
*/ */
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => { EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine__default['default'] SelectorEngine__default['default'].find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
.find(SELECTOR_DATA_SPY)
.forEach((spy) => new ScrollSpy(spy, Manipulator__default['default'].getDataAttributes(spy)));
}); });
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap tab.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap tab.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -34,7 +34,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -55,7 +55,7 @@
} // Just in case some CMS puts out a full URL with the anchor appended } // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -168,7 +168,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tab.js * Bootstrap (v5.0.0): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -213,10 +213,9 @@
show() { show() {
if ( if (
(this._element.parentNode && this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
this._element.classList.contains(CLASS_NAME_ACTIVE)) || this._element.classList.contains(CLASS_NAME_ACTIVE)
isDisabled(this._element)
) { ) {
return; return;
} }
@ -315,12 +314,18 @@
element.classList.add(CLASS_NAME_SHOW); element.classList.add(CLASS_NAME_SHOW);
} }
if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) { let parent = element.parentNode;
if (parent && parent.nodeName === 'LI') {
parent = parent.parentNode;
}
if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
const dropdownElement = element.closest(SELECTOR_DROPDOWN); const dropdownElement = element.closest(SELECTOR_DROPDOWN);
if (dropdownElement) { if (dropdownElement) {
SelectorEngine__default['default'] SelectorEngine__default['default']
.find(SELECTOR_DROPDOWN_TOGGLE) .find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement)
.forEach((dropdown) => dropdown.classList.add(CLASS_NAME_ACTIVE)); .forEach((dropdown) => dropdown.classList.add(CLASS_NAME_ACTIVE));
} }
@ -357,7 +362,14 @@
EVENT_CLICK_DATA_API, EVENT_CLICK_DATA_API,
SELECTOR_DATA_TOGGLE, SELECTOR_DATA_TOGGLE,
function (event) { function (event) {
event.preventDefault(); if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault();
}
if (isDisabled(this)) {
return;
}
const data = Data__default['default'].get(this, DATA_KEY) || new Tab(this); const data = Data__default['default'].get(this, DATA_KEY) || new Tab(this);
data.show(); data.show();
} }

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap toast.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap toast.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -34,7 +34,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -105,9 +105,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -153,7 +151,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): toast.js * Bootstrap (v5.0.0): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -290,7 +288,6 @@
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
} }
EventHandler__default['default'].off(this._element, EVENT_CLICK_DISMISS);
super.dispose(); super.dispose();
this._config = null; this._config = null;
} // Private } // Private

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap tooltip.js v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap tooltip.js v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ */
@ -73,7 +73,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -158,9 +158,7 @@
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -187,7 +185,7 @@
return findShadowRoot(element.parentNode); return findShadowRoot(element.parentNode);
}; };
const noop = () => function () {}; const noop = () => {};
const getjQuery = () => { const getjQuery = () => {
const { jQuery } = window; const { jQuery } = window;
@ -229,7 +227,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/sanitizer.js * Bootstrap (v5.0.0): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -353,7 +351,7 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tooltip.js * Bootstrap (v5.0.0): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -530,7 +528,6 @@
dispose() { dispose() {
clearTimeout(this._timeout); clearTimeout(this._timeout);
EventHandler__default['default'].off(this._element, this.constructor.EVENT_KEY);
EventHandler__default['default'].off( EventHandler__default['default'].off(
this._element.closest(`.${CLASS_NAME_MODAL}`), this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal', 'hide.bs.modal',
@ -634,7 +631,7 @@
if ('ontouchstart' in document.documentElement) { if ('ontouchstart' in document.documentElement) {
[].concat(...document.body.children).forEach((element) => { [].concat(...document.body.children).forEach((element) => {
EventHandler__default['default'].on(element, 'mouseover', noop()); EventHandler__default['default'].on(element, 'mouseover', noop);
}); });
} }
@ -840,7 +837,6 @@
{ {
name: 'flip', name: 'flip',
options: { options: {
altBoundary: true,
fallbackPlacements: this.config.fallbackPlacements, fallbackPlacements: this.config.fallbackPlacements,
}, },
}, },

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): alert.js * Bootstrap (v5.0.0): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,11 +1,12 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): base-component.js * Bootstrap (v5.0.0): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import Data from './dom/data'; import Data from './dom/data';
import EventHandler from './dom/event-handler';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -13,7 +14,7 @@ import Data from './dom/data';
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const VERSION = '5.0.0-beta3'; const VERSION = '5.0.0';
class BaseComponent { class BaseComponent {
constructor(element) { constructor(element) {
@ -29,6 +30,7 @@ class BaseComponent {
dispose() { dispose() {
Data.remove(this._element, this.constructor.DATA_KEY); Data.remove(this._element, this.constructor.DATA_KEY);
EventHandler.off(this._element, `.${this.constructor.DATA_KEY}`);
this._element = null; this._element = null;
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): button.js * Bootstrap (v5.0.0): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): carousel.js * Bootstrap (v5.0.0): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -215,8 +215,6 @@ class Carousel extends BaseComponent {
} }
dispose() { dispose() {
EventHandler.off(this._element, EVENT_KEY);
this._items = null; this._items = null;
this._config = null; this._config = null;
this._interval = null; this._interval = null;
@ -343,10 +341,10 @@ class Carousel extends BaseComponent {
if (event.key === ARROW_LEFT_KEY) { if (event.key === ARROW_LEFT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_LEFT); this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) { } else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_RIGHT); this._slide(DIRECTION_LEFT);
} }
} }
@ -520,10 +518,10 @@ class Carousel extends BaseComponent {
} }
if (isRTL()) { if (isRTL()) {
return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT; return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
} }
return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV; return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
} }
_orderToDirection(order) { _orderToDirection(order) {
@ -532,10 +530,10 @@ class Carousel extends BaseComponent {
} }
if (isRTL()) { if (isRTL()) {
return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT; return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
} }
return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT; return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
} }
// Static // Static

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): collapse.js * Bootstrap (v5.0.0): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

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

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/event-handler.js * Bootstrap (v5.0.0): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -22,6 +22,7 @@ const customEvents = {
mouseenter: 'mouseover', mouseenter: 'mouseover',
mouseleave: 'mouseout', mouseleave: 'mouseout',
}; };
const customEventsRegex = /^(mouseenter|mouseleave)/i;
const nativeEvents = new Set([ const nativeEvents = new Set([
'click', 'click',
'dblclick', 'dblclick',
@ -113,7 +114,7 @@ function bootstrapDelegationHandler(element, selector, fn) {
if (handler.oneOff) { if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring // eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, fn); EventHandler.off(element, event.type, selector, fn);
} }
return fn.apply(target, [event]); return fn.apply(target, [event]);
@ -144,14 +145,7 @@ function normalizeParams(originalTypeEvent, handler, delegationFn) {
const delegation = typeof handler === 'string'; const delegation = typeof handler === 'string';
const originalHandler = delegation ? delegationFn : handler; const originalHandler = delegation ? delegationFn : handler;
// allow to get the native events from namespaced events ('click.bs.button' --> 'click') let typeEvent = getTypeEvent(originalTypeEvent);
let typeEvent = originalTypeEvent.replace(stripNameRegex, '');
const custom = customEvents[typeEvent];
if (custom) {
typeEvent = custom;
}
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);
if (!isNative) { if (!isNative) {
@ -171,6 +165,28 @@ function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
delegationFn = null; delegationFn = null;
} }
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
if (customEventsRegex.test(originalTypeEvent)) {
const wrapFn = (fn) => {
return function (event) {
if (
!event.relatedTarget ||
(event.relatedTarget !== event.delegateTarget &&
!event.delegateTarget.contains(event.relatedTarget))
) {
return fn.call(this, event);
}
};
};
if (delegationFn) {
delegationFn = wrapFn(delegationFn);
} else {
handler = wrapFn(handler);
}
}
const [delegation, originalHandler, typeEvent] = normalizeParams( const [delegation, originalHandler, typeEvent] = normalizeParams(
originalTypeEvent, originalTypeEvent,
handler, handler,
@ -223,6 +239,12 @@ function removeNamespacedHandlers(element, events, typeEvent, namespace) {
}); });
} }
function getTypeEvent(event) {
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
event = event.replace(stripNameRegex, '');
return customEvents[event] || event;
}
const EventHandler = { const EventHandler = {
on(element, event, handler, delegationFn) { on(element, event, handler, delegationFn) {
addHandler(element, event, handler, delegationFn, false); addHandler(element, event, handler, delegationFn, false);
@ -280,7 +302,7 @@ const EventHandler = {
} }
const $ = getjQuery(); const $ = getjQuery();
const typeEvent = event.replace(stripNameRegex, ''); const typeEvent = getTypeEvent(event);
const inNamespace = event !== typeEvent; const inNamespace = event !== typeEvent;
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);

View File

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

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/selector-engine.js * Bootstrap (v5.0.0): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dropdown.js * Bootstrap (v5.0.0): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -10,6 +10,7 @@ import * as Popper from '@popperjs/core';
import { import {
defineJQueryPlugin, defineJQueryPlugin,
getElementFromSelector, getElementFromSelector,
isDisabled,
isElement, isElement,
isVisible, isVisible,
isRTL, isRTL,
@ -51,7 +52,6 @@ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYDOWN_DATA_API = `keydown${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}`; const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_DISABLED = 'disabled';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_DROPUP = 'dropup'; const CLASS_NAME_DROPUP = 'dropup';
const CLASS_NAME_DROPEND = 'dropend'; const CLASS_NAME_DROPEND = 'dropend';
@ -76,6 +76,7 @@ const Default = {
reference: 'toggle', reference: 'toggle',
display: 'dynamic', display: 'dynamic',
popperConfig: null, popperConfig: null,
autoClose: true,
}; };
const DefaultType = { const DefaultType = {
@ -84,6 +85,7 @@ const DefaultType = {
reference: '(string|element|object)', reference: '(string|element|object)',
display: 'string', display: 'string',
popperConfig: '(null|object|function)', popperConfig: '(null|object|function)',
autoClose: '(boolean|string)',
}; };
/** /**
@ -121,15 +123,14 @@ class Dropdown extends BaseComponent {
// Public // Public
toggle() { toggle() {
if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) { if (isDisabled(this._element)) {
return; return;
} }
const isActive = this._element.classList.contains(CLASS_NAME_SHOW); const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
Dropdown.clearMenus();
if (isActive) { if (isActive) {
this.hide();
return; return;
} }
@ -137,11 +138,7 @@ class Dropdown extends BaseComponent {
} }
show() { show() {
if ( if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
@ -198,7 +195,7 @@ class Dropdown extends BaseComponent {
if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) { if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
[] []
.concat(...document.body.children) .concat(...document.body.children)
.forEach((elem) => EventHandler.on(elem, 'mouseover', null, noop())); .forEach((elem) => EventHandler.on(elem, 'mouseover', noop));
} }
this._element.focus(); this._element.focus();
@ -210,11 +207,7 @@ class Dropdown extends BaseComponent {
} }
hide() { hide() {
if ( if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
!this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
@ -222,24 +215,10 @@ class Dropdown extends BaseComponent {
relatedTarget: this._element, relatedTarget: this._element,
}; };
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget); this._completeHide(relatedTarget);
if (hideEvent.defaultPrevented) {
return;
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
Manipulator.removeDataAttribute(this._menu, 'popper');
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
} }
dispose() { dispose() {
EventHandler.off(this._element, EVENT_KEY);
this._menu = null; this._menu = null;
if (this._popper) { if (this._popper) {
@ -266,6 +245,31 @@ class Dropdown extends BaseComponent {
}); });
} }
_completeHide(relatedTarget) {
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget);
if (hideEvent.defaultPrevented) {
return;
}
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler.off(elem, 'mouseover', noop));
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.remove(CLASS_NAME_SHOW);
this._element.classList.remove(CLASS_NAME_SHOW);
this._element.setAttribute('aria-expanded', 'false');
Manipulator.removeDataAttribute(this._menu, 'popper');
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
}
_getConfig(config) { _getConfig(config) {
config = { config = {
...this.constructor.Default, ...this.constructor.Default,
@ -369,6 +373,31 @@ class Dropdown extends BaseComponent {
}; };
} }
_selectMenuItem(event) {
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();
}
// Static // Static
static dropdownInterface(element, config) { static dropdownInterface(element, config) {
@ -403,7 +432,7 @@ class Dropdown extends BaseComponent {
return; return;
} }
if (/input|select|textarea|form/i.test(event.target.tagName)) { if (/input|select|option|textarea|form/i.test(event.target.tagName)) {
return; return;
} }
} }
@ -412,26 +441,26 @@ class Dropdown extends BaseComponent {
for (let i = 0, len = toggles.length; i < len; i++) { for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data.get(toggles[i], DATA_KEY); const context = Data.get(toggles[i], DATA_KEY);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
continue;
}
const relatedTarget = { const relatedTarget = {
relatedTarget: toggles[i], relatedTarget: context._element,
}; };
if (event && event.type === 'click') {
relatedTarget.clickEvent = event;
}
if (!context) {
continue;
}
const dropdownMenu = context._menu;
if (!toggles[i].classList.contains(CLASS_NAME_SHOW)) {
continue;
}
if (event) { if (event) {
// Don't close the menu if the clicked element or one of its parents is the dropdown button const composedPath = event.composedPath();
if ([context._element].some((element) => event.composedPath().includes(element))) { const isMenuTarget = composedPath.includes(context._menu);
if (
composedPath.includes(context._element) ||
(context._config.autoClose === 'inside' && !isMenuTarget) ||
(context._config.autoClose === 'outside' && isMenuTarget)
) {
continue; continue;
} }
@ -439,35 +468,17 @@ class Dropdown extends BaseComponent {
if ( if (
event.type === 'keyup' && event.type === 'keyup' &&
event.key === TAB_KEY && event.key === TAB_KEY &&
dropdownMenu.contains(event.target) context._menu.contains(event.target)
) { ) {
continue; continue;
} }
if (event.type === 'click') {
relatedTarget.clickEvent = event;
}
} }
const hideEvent = EventHandler.trigger(toggles[i], EVENT_HIDE, relatedTarget); context._completeHide(relatedTarget);
if (hideEvent.defaultPrevented) {
continue;
}
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler.off(elem, 'mouseover', null, noop()));
}
toggles[i].setAttribute('aria-expanded', 'false');
if (context._popper) {
context._popper.destroy();
}
dropdownMenu.classList.remove(CLASS_NAME_SHOW);
toggles[i].classList.remove(CLASS_NAME_SHOW);
Manipulator.removeDataAttribute(dropdownMenu, 'popper');
EventHandler.trigger(toggles[i], EVENT_HIDDEN, relatedTarget);
} }
} }
@ -494,30 +505,32 @@ class Dropdown extends BaseComponent {
return; return;
} }
event.preventDefault(); const isActive = this.classList.contains(CLASS_NAME_SHOW);
event.stopPropagation();
if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) { if (!isActive && event.key === ESCAPE_KEY) {
return; return;
} }
const parent = Dropdown.getParentFromElement(this); event.preventDefault();
const isActive = this.classList.contains(CLASS_NAME_SHOW); event.stopPropagation();
if (event.key === ESCAPE_KEY) { if (isDisabled(this)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
? this ? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]; : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
button.focus();
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus(); Dropdown.clearMenus();
return; return;
} }
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) { if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) getToggleButton().click();
? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
button.click();
return; return;
} }
@ -526,28 +539,7 @@ class Dropdown extends BaseComponent {
return; return;
} }
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible); Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
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();
} }
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): modal.js * Bootstrap (v5.0.0): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -10,16 +10,21 @@ import {
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isVisible,
isRTL, isRTL,
isVisible,
reflow, reflow,
typeCheckConfig, typeCheckConfig,
} from './util/index'; } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler'; import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
import {
getWidth as getScrollBarWidth,
hide as scrollBarHide,
reset as scrollBarReset,
} from './util/scrollbar';
import BaseComponent from './base-component'; import BaseComponent from './base-component';
import Backdrop from './util/backdrop';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -58,8 +63,6 @@ const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`;
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`; const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_OPEN = 'modal-open'; const CLASS_NAME_OPEN = 'modal-open';
const CLASS_NAME_FADE = 'fade'; const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
@ -69,8 +72,6 @@ const SELECTOR_DIALOG = '.modal-dialog';
const SELECTOR_MODAL_BODY = '.modal-body'; const SELECTOR_MODAL_BODY = '.modal-body';
const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="modal"]'; const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="modal"]';
const SELECTOR_DATA_DISMISS = '[data-mdb-dismiss="modal"]'; const SELECTOR_DATA_DISMISS = '[data-mdb-dismiss="modal"]';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -84,12 +85,10 @@ class Modal extends BaseComponent {
this._config = this._getConfig(config); this._config = this._getConfig(config);
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
this._backdrop = null; this._backdrop = this._initializeBackDrop();
this._isShown = false; this._isShown = false;
this._isBodyOverflowing = false;
this._ignoreBackdropClick = false; this._ignoreBackdropClick = false;
this._isTransitioning = false; this._isTransitioning = false;
this._scrollbarWidth = 0;
} }
// Getters // Getters
@ -127,8 +126,9 @@ class Modal extends BaseComponent {
this._isShown = true; this._isShown = true;
this._checkScrollbar(); scrollBarHide();
this._setScrollbar();
document.body.classList.add(CLASS_NAME_OPEN);
this._adjustDialog(); this._adjustDialog();
@ -193,9 +193,7 @@ class Modal extends BaseComponent {
} }
dispose() { dispose() {
[window, this._element, this._dialog].forEach((htmlElement) => [window, this._dialog].forEach((htmlElement) => EventHandler.off(htmlElement, EVENT_KEY));
EventHandler.off(htmlElement, EVENT_KEY)
);
super.dispose(); super.dispose();
@ -208,12 +206,11 @@ class Modal extends BaseComponent {
this._config = null; this._config = null;
this._dialog = null; this._dialog = null;
this._backdrop.dispose();
this._backdrop = null; this._backdrop = null;
this._isShown = null; this._isShown = null;
this._isBodyOverflowing = null;
this._ignoreBackdropClick = null; this._ignoreBackdropClick = null;
this._isTransitioning = null; this._isTransitioning = null;
this._scrollbarWidth = null;
} }
handleUpdate() { handleUpdate() {
@ -222,6 +219,13 @@ class Modal extends BaseComponent {
// Private // Private
_initializeBackDrop() {
return new Backdrop({
isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value
isAnimated: this._isAnimated(),
});
}
_getConfig(config) { _getConfig(config) {
config = { config = {
...Default, ...Default,
@ -324,81 +328,33 @@ class Modal extends BaseComponent {
this._element.removeAttribute('aria-modal'); this._element.removeAttribute('aria-modal');
this._element.removeAttribute('role'); this._element.removeAttribute('role');
this._isTransitioning = false; this._isTransitioning = false;
this._showBackdrop(() => { this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN); document.body.classList.remove(CLASS_NAME_OPEN);
this._resetAdjustments(); this._resetAdjustments();
this._resetScrollbar(); scrollBarReset();
EventHandler.trigger(this._element, EVENT_HIDDEN); EventHandler.trigger(this._element, EVENT_HIDDEN);
}); });
} }
_removeBackdrop() {
this._backdrop.parentNode.removeChild(this._backdrop);
this._backdrop = null;
}
_showBackdrop(callback) { _showBackdrop(callback) {
const isAnimated = this._isAnimated(); EventHandler.on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._isShown && this._config.backdrop) { if (this._ignoreBackdropClick) {
this._backdrop = document.createElement('div'); this._ignoreBackdropClick = false;
this._backdrop.className = CLASS_NAME_BACKDROP;
if (isAnimated) {
this._backdrop.classList.add(CLASS_NAME_FADE);
}
document.body.appendChild(this._backdrop);
EventHandler.on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false;
return;
}
if (event.target !== event.currentTarget) {
return;
}
if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
} else {
this.hide();
}
});
if (isAnimated) {
reflow(this._backdrop);
}
this._backdrop.classList.add(CLASS_NAME_SHOW);
if (!isAnimated) {
callback();
return; return;
} }
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); if (event.target !== event.currentTarget) {
return;
EventHandler.one(this._backdrop, 'transitionend', callback);
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else if (!this._isShown && this._backdrop) {
this._backdrop.classList.remove(CLASS_NAME_SHOW);
const callbackRemove = () => {
this._removeBackdrop();
callback();
};
if (isAnimated) {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop);
EventHandler.one(this._backdrop, 'transitionend', callbackRemove);
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else {
callbackRemove();
} }
} else {
callback(); if (this._config.backdrop === true) {
} this.hide();
} else if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
}
});
this._backdrop.show(callback);
} }
_isAnimated() { _isAnimated() {
@ -439,19 +395,21 @@ class Modal extends BaseComponent {
_adjustDialog() { _adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getScrollBarWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if ( if (
(!this._isBodyOverflowing && isModalOverflowing && !isRTL()) || (!isBodyOverflowing && isModalOverflowing && !isRTL()) ||
(this._isBodyOverflowing && !isModalOverflowing && isRTL()) (isBodyOverflowing && !isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingLeft = `${this._scrollbarWidth}px`; this._element.style.paddingLeft = `${scrollbarWidth}px`;
} }
if ( if (
(this._isBodyOverflowing && !isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && !isRTL()) ||
(!this._isBodyOverflowing && isModalOverflowing && isRTL()) (!isBodyOverflowing && isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingRight = `${this._scrollbarWidth}px`; this._element.style.paddingRight = `${scrollbarWidth}px`;
} }
} }
@ -460,100 +418,22 @@ class Modal extends BaseComponent {
this._element.style.paddingRight = ''; this._element.style.paddingRight = '';
} }
_checkScrollbar() {
const rect = document.body.getBoundingClientRect();
this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
this._scrollbarWidth = this._getScrollbarWidth();
}
_setScrollbar() {
if (this._isBodyOverflowing) {
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
this._setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - this._scrollbarWidth
);
this._setElementAttributes(
'body',
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
}
document.body.classList.add(CLASS_NAME_OPEN);
}
_setElementAttributes(selector, styleProp, callback) {
SelectorEngine.find(selector).forEach((element) => {
if (
element !== document.body &&
window.innerWidth > element.clientWidth + this._scrollbarWidth
) {
return;
}
const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px';
});
}
_resetScrollbar() {
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
this._resetElementAttributes('body', 'paddingRight');
}
_resetElementAttributes(selector, styleProp) {
SelectorEngine.find(selector).forEach((element) => {
const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) {
element.style[styleProp] = '';
} else {
Manipulator.removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
}
_getScrollbarWidth() {
// thx d.walsh
const scrollDiv = document.createElement('div');
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
// Static // Static
static jQueryInterface(config, relatedTarget) { static jQueryInterface(config, relatedTarget) {
return this.each(function () { return this.each(function () {
let data = Data.get(this, DATA_KEY); const data =
const _config = { Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
...Default,
...Manipulator.getDataAttributes(this),
...(typeof config === 'object' && config ? config : {}),
};
if (!data) { if (typeof config !== 'string') {
data = new Modal(this, _config); return;
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config](relatedTarget);
} }
data[config](relatedTarget);
}); });
} }
} }
@ -567,7 +447,7 @@ class Modal extends BaseComponent {
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
const target = getElementFromSelector(this); const target = getElementFromSelector(this);
if (this.tagName === 'A' || this.tagName === 'AREA') { if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault(); event.preventDefault();
} }
@ -584,15 +464,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
}); });
}); });
let data = Data.get(target, DATA_KEY); const data = Modal.getInstance(target) || new Modal(target);
if (!data) {
const config = {
...Manipulator.getDataAttributes(target),
...Manipulator.getDataAttributes(this),
};
data = new Modal(target, config);
}
data.toggle(this); data.toggle(this);
}); });

View File

@ -1,14 +1,14 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): offcanvas.js * Bootstrap (v5.0.0): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import { import {
defineJQueryPlugin, defineJQueryPlugin,
emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
getSelectorFromElement,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isDisabled, isDisabled,
isVisible, isVisible,
@ -20,6 +20,7 @@ import EventHandler from './dom/event-handler';
import BaseComponent from './base-component'; import BaseComponent from './base-component';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import Backdrop from './util/backdrop';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -46,11 +47,8 @@ const DefaultType = {
scroll: 'boolean', scroll: 'boolean',
}; };
const CLASS_NAME_BACKDROP_BODY = 'offcanvas-backdrop';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_TOGGLING = 'offcanvas-toggling';
const OPEN_SELECTOR = '.offcanvas.show'; const OPEN_SELECTOR = '.offcanvas.show';
const ACTIVE_SELECTOR = `${OPEN_SELECTOR}, .${CLASS_NAME_TOGGLING}`;
const EVENT_SHOW = `show${EVENT_KEY}`; const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`; const EVENT_SHOWN = `shown${EVENT_KEY}`;
@ -59,6 +57,7 @@ const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_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_DISMISS = '[data-mdb-dismiss="offcanvas"]';
const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="offcanvas"]'; const SELECTOR_DATA_TOGGLE = '[data-mdb-toggle="offcanvas"]';
@ -75,6 +74,7 @@ class Offcanvas extends BaseComponent {
this._config = this._getConfig(config); this._config = this._getConfig(config);
this._isShown = false; this._isShown = false;
this._backdrop = this._initializeBackDrop();
this._addEventListeners(); this._addEventListeners();
} }
@ -108,27 +108,25 @@ class Offcanvas extends BaseComponent {
this._isShown = true; this._isShown = true;
this._element.style.visibility = 'visible'; this._element.style.visibility = 'visible';
if (this._config.backdrop) { this._backdrop.show();
document.body.classList.add(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarHide(); scrollBarHide();
this._enforceFocusOnElement(this._element);
} }
this._element.classList.add(CLASS_NAME_TOGGLING);
this._element.removeAttribute('aria-hidden'); this._element.removeAttribute('aria-hidden');
this._element.setAttribute('aria-modal', true); this._element.setAttribute('aria-modal', true);
this._element.setAttribute('role', 'dialog'); this._element.setAttribute('role', 'dialog');
this._element.classList.add(CLASS_NAME_SHOW); this._element.classList.add(CLASS_NAME_SHOW);
const completeCallBack = () => { const completeCallBack = () => {
this._element.classList.remove(CLASS_NAME_TOGGLING);
EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget }); EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget });
this._enforceFocusOnElement(this._element);
}; };
setTimeout(completeCallBack, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler.one(this._element, 'transitionend', completeCallBack);
emulateTransitionEnd(this._element, transitionDuration);
} }
hide() { hide() {
@ -142,11 +140,11 @@ class Offcanvas extends BaseComponent {
return; return;
} }
this._element.classList.add(CLASS_NAME_TOGGLING);
EventHandler.off(document, EVENT_FOCUSIN); EventHandler.off(document, EVENT_FOCUSIN);
this._element.blur(); this._element.blur();
this._isShown = false; this._isShown = false;
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
this._backdrop.hide();
const completeCallback = () => { const completeCallback = () => {
this._element.setAttribute('aria-hidden', true); this._element.setAttribute('aria-hidden', true);
@ -154,19 +152,25 @@ class Offcanvas extends BaseComponent {
this._element.removeAttribute('role'); this._element.removeAttribute('role');
this._element.style.visibility = 'hidden'; this._element.style.visibility = 'hidden';
if (this._config.backdrop) {
document.body.classList.remove(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarReset(); scrollBarReset();
} }
EventHandler.trigger(this._element, EVENT_HIDDEN); EventHandler.trigger(this._element, EVENT_HIDDEN);
this._element.classList.remove(CLASS_NAME_TOGGLING);
}; };
setTimeout(completeCallback, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler.one(this._element, 'transitionend', completeCallback);
emulateTransitionEnd(this._element, transitionDuration);
}
dispose() {
this._backdrop.dispose();
super.dispose();
EventHandler.off(document, EVENT_FOCUSIN);
this._config = null;
this._backdrop = null;
} }
// Private // Private
@ -181,6 +185,15 @@ class Offcanvas extends BaseComponent {
return config; return config;
} }
_initializeBackDrop() {
return new Backdrop({
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
clickCallback: () => this.hide(),
});
}
_enforceFocusOnElement(element) { _enforceFocusOnElement(element) {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => { EventHandler.on(document, EVENT_FOCUSIN, (event) => {
@ -198,18 +211,11 @@ class Offcanvas extends BaseComponent {
_addEventListeners() { _addEventListeners() {
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide()); EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(document, 'keydown', (event) => { EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.key === ESCAPE_KEY) { if (this._config.keyboard && event.key === ESCAPE_KEY) {
this.hide(); this.hide();
} }
}); });
EventHandler.on(document, EVENT_CLICK_DATA_API, (event) => {
const target = SelectorEngine.findOne(getSelectorFromElement(event.target));
if (!this._element.contains(event.target) && target !== this._element) {
this.hide();
}
});
} }
// Static // Static
@ -257,9 +263,9 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
}); });
// avoid conflict when clicking a toggler of an offcanvas, while another is open // avoid conflict when clicking a toggler of an offcanvas, while another is open
const allReadyOpen = SelectorEngine.findOne(ACTIVE_SELECTOR); const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
if (allReadyOpen && allReadyOpen !== target) { if (allReadyOpen && allReadyOpen !== target) {
return; Offcanvas.getInstance(allReadyOpen).hide();
} }
const data = Data.get(target, DATA_KEY) || new Offcanvas(target); const data = Data.get(target, DATA_KEY) || new Offcanvas(target);

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): popover.js * Bootstrap (v5.0.0): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): scrollspy.js * Bootstrap (v5.0.0): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -12,7 +12,6 @@ import {
isElement, isElement,
typeCheckConfig, typeCheckConfig,
} from './util/index'; } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler'; import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
@ -148,6 +147,7 @@ class ScrollSpy extends BaseComponent {
_getConfig(config) { _getConfig(config) {
config = { config = {
...Default, ...Default,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {}), ...(typeof config === 'object' && config ? config : {}),
}; };
@ -276,20 +276,19 @@ class ScrollSpy extends BaseComponent {
static jQueryInterface(config) { static jQueryInterface(config) {
return this.each(function () { return this.each(function () {
let data = Data.get(this, DATA_KEY); const data =
const _config = typeof config === 'object' && config; ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
if (!data) { if (typeof config !== 'string') {
data = new ScrollSpy(this, _config); return;
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config]();
} }
data[config]();
}); });
} }
} }
@ -301,9 +300,7 @@ class ScrollSpy extends BaseComponent {
*/ */
EventHandler.on(window, EVENT_LOAD_DATA_API, () => { EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine.find(SELECTOR_DATA_SPY).forEach( SelectorEngine.find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
(spy) => new ScrollSpy(spy, Manipulator.getDataAttributes(spy))
);
}); });
/** /**

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tab.js * Bootstrap (v5.0.0): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -66,10 +66,9 @@ class Tab extends BaseComponent {
show() { show() {
if ( if (
(this._element.parentNode && this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
this._element.classList.contains(CLASS_NAME_ACTIVE)) || this._element.classList.contains(CLASS_NAME_ACTIVE)
isDisabled(this._element)
) { ) {
return; return;
} }
@ -172,11 +171,16 @@ class Tab extends BaseComponent {
element.classList.add(CLASS_NAME_SHOW); element.classList.add(CLASS_NAME_SHOW);
} }
if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) { let parent = element.parentNode;
if (parent && parent.nodeName === 'LI') {
parent = parent.parentNode;
}
if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
const dropdownElement = element.closest(SELECTOR_DROPDOWN); const dropdownElement = element.closest(SELECTOR_DROPDOWN);
if (dropdownElement) { if (dropdownElement) {
SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE).forEach((dropdown) => SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach((dropdown) =>
dropdown.classList.add(CLASS_NAME_ACTIVE) dropdown.classList.add(CLASS_NAME_ACTIVE)
); );
} }
@ -213,7 +217,13 @@ class Tab extends BaseComponent {
*/ */
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault(); if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault();
}
if (isDisabled(this)) {
return;
}
const data = Data.get(this, DATA_KEY) || new Tab(this); const data = Data.get(this, DATA_KEY) || new Tab(this);
data.show(); data.show();

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): toast.js * Bootstrap (v5.0.0): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -156,8 +156,6 @@ class Toast extends BaseComponent {
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
} }
EventHandler.off(this._element, EVENT_CLICK_DISMISS);
super.dispose(); super.dispose();
this._config = null; this._config = null;
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tooltip.js * Bootstrap (v5.0.0): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -213,7 +213,6 @@ class Tooltip extends BaseComponent {
dispose() { dispose() {
clearTimeout(this._timeout); clearTimeout(this._timeout);
EventHandler.off(this._element, this.constructor.EVENT_KEY);
EventHandler.off( EventHandler.off(
this._element.closest(`.${CLASS_NAME_MODAL}`), this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal', 'hide.bs.modal',
@ -308,7 +307,7 @@ class Tooltip extends BaseComponent {
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement) { if ('ontouchstart' in document.documentElement) {
[].concat(...document.body.children).forEach((element) => { [].concat(...document.body.children).forEach((element) => {
EventHandler.on(element, 'mouseover', noop()); EventHandler.on(element, 'mouseover', noop);
}); });
} }
@ -512,7 +511,6 @@ class Tooltip extends BaseComponent {
{ {
name: 'flip', name: 'flip',
options: { options: {
altBoundary: true,
fallbackPlacements: this.config.fallbackPlacements, fallbackPlacements: this.config.fallbackPlacements,
}, },
}, },

View File

@ -0,0 +1,139 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): util/backdrop.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import {
emulateTransitionEnd,
execute,
getTransitionDurationFromElement,
reflow,
typeCheckConfig,
} from './index';
const Default = {
isVisible: true, // if false, we use the backdrop helper without adding any element to the dom
isAnimated: false,
rootElement: document.body, // give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType = {
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
clickCallback: '(function|null)',
};
const NAME = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`;
class Backdrop {
constructor(config) {
this._config = this._getConfig(config);
this._isAppended = false;
this._element = null;
}
show(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._append();
if (this._config.isAnimated) {
reflow(this._getElement());
}
this._getElement().classList.add(CLASS_NAME_SHOW);
this._emulateAnimation(() => {
execute(callback);
});
}
hide(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._getElement().classList.remove(CLASS_NAME_SHOW);
this._emulateAnimation(() => {
this.dispose();
execute(callback);
});
}
// Private
_getElement() {
if (!this._element) {
const backdrop = document.createElement('div');
backdrop.className = CLASS_NAME_BACKDROP;
if (this._config.isAnimated) {
backdrop.classList.add(CLASS_NAME_FADE);
}
this._element = backdrop;
}
return this._element;
}
_getConfig(config) {
config = {
...Default,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
}
_append() {
if (this._isAppended) {
return;
}
this._config.rootElement.appendChild(this._getElement());
EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
});
this._isAppended = true;
}
dispose() {
if (!this._isAppended) {
return;
}
EventHandler.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler.one(this._getElement(), 'transitionend', () => execute(callback));
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
}
}
export default Backdrop;

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -51,7 +51,7 @@ const getSelector = (element) => {
// Just in case some CMS puts out a full URL with the anchor appended // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -134,9 +134,7 @@ const typeCheckConfig = (componentName, config, configTypes) => {
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -200,7 +198,7 @@ const findShadowRoot = (element) => {
return findShadowRoot(element.parentNode); return findShadowRoot(element.parentNode);
}; };
const noop = () => function () {}; const noop = () => {};
const reflow = (element) => element.offsetHeight; const reflow = (element) => element.offsetHeight;
@ -240,6 +238,12 @@ const defineJQueryPlugin = (name, plugin) => {
}); });
}; };
const execute = (callback) => {
if (typeof callback === 'function') {
callback();
}
};
export { export {
getUID, getUID,
getSelectorFromElement, getSelectorFromElement,
@ -258,4 +262,5 @@ export {
onDOMContentLoaded, onDOMContentLoaded,
isRTL, isRTL,
defineJQueryPlugin, defineJQueryPlugin,
execute,
}; };

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/sanitizer.js * Bootstrap (v5.0.0): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/scrollBar.js * Bootstrap (v5.0.0): util/scrollBar.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -8,7 +8,7 @@
import SelectorEngine from '../dom/selector-engine'; import SelectorEngine from '../dom/selector-engine';
import Manipulator from '../dom/manipulator'; import Manipulator from '../dom/manipulator';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed'; const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top'; const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => { const getWidth = () => {
@ -18,7 +18,10 @@ const getWidth = () => {
}; };
const hide = (width = getWidth()) => { const hide = (width = getWidth()) => {
document.body.style.overflow = 'hidden'; _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( _setElementAttributes(
SELECTOR_FIXED_CONTENT, SELECTOR_FIXED_CONTENT,
'paddingRight', 'paddingRight',
@ -29,7 +32,15 @@ const hide = (width = getWidth()) => {
'marginRight', 'marginRight',
(calculatedValue) => calculatedValue - width (calculatedValue) => calculatedValue - width
); );
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); };
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
}; };
const _setElementAttributes = (selector, styleProp, callback) => { const _setElementAttributes = (selector, styleProp, callback) => {
@ -42,21 +53,21 @@ const _setElementAttributes = (selector, styleProp, callback) => {
const actualValue = element.style[styleProp]; const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp]; const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.setDataAttribute(element, styleProp, actualValue); Manipulator.setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px'; element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
}); });
}; };
const reset = () => { const reset = () => {
document.body.style.overflow = 'auto'; _resetElementAttributes('body', 'overflow');
_resetElementAttributes('body', 'paddingRight');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight'); _resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight'); _resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
_resetElementAttributes('body', 'paddingRight');
}; };
const _resetElementAttributes = (selector, styleProp) => { const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach((element) => { SelectorEngine.find(selector).forEach((element) => {
const value = Manipulator.getDataAttribute(element, styleProp); const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) { if (typeof value === 'undefined') {
element.style.removeProperty(styleProp); element.style.removeProperty(styleProp);
} else { } else {
Manipulator.removeDataAttribute(element, styleProp); Manipulator.removeDataAttribute(element, styleProp);

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): alert.js * Bootstrap (v5.0.0): alert.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,11 +1,12 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): base-component.js * Bootstrap (v5.0.0): base-component.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import Data from './dom/data'; import Data from './dom/data';
import EventHandler from './dom/event-handler';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -13,7 +14,7 @@ import Data from './dom/data';
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
*/ */
const VERSION = '5.0.0-beta3'; const VERSION = '5.0.0';
class BaseComponent { class BaseComponent {
constructor(element) { constructor(element) {
@ -29,6 +30,7 @@ class BaseComponent {
dispose() { dispose() {
Data.remove(this._element, this.constructor.DATA_KEY); Data.remove(this._element, this.constructor.DATA_KEY);
EventHandler.off(this._element, `.${this.constructor.DATA_KEY}`);
this._element = null; this._element = null;
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): button.js * Bootstrap (v5.0.0): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): carousel.js * Bootstrap (v5.0.0): carousel.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -215,8 +215,6 @@ class Carousel extends BaseComponent {
} }
dispose() { dispose() {
EventHandler.off(this._element, EVENT_KEY);
this._items = null; this._items = null;
this._config = null; this._config = null;
this._interval = null; this._interval = null;
@ -343,10 +341,10 @@ class Carousel extends BaseComponent {
if (event.key === ARROW_LEFT_KEY) { if (event.key === ARROW_LEFT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_LEFT); this._slide(DIRECTION_RIGHT);
} else if (event.key === ARROW_RIGHT_KEY) { } else if (event.key === ARROW_RIGHT_KEY) {
event.preventDefault(); event.preventDefault();
this._slide(DIRECTION_RIGHT); this._slide(DIRECTION_LEFT);
} }
} }
@ -520,10 +518,10 @@ class Carousel extends BaseComponent {
} }
if (isRTL()) { if (isRTL()) {
return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT; return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
} }
return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV; return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
} }
_orderToDirection(order) { _orderToDirection(order) {
@ -532,10 +530,10 @@ class Carousel extends BaseComponent {
} }
if (isRTL()) { if (isRTL()) {
return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT; return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
} }
return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT; return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
} }
// Static // Static

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): collapse.js * Bootstrap (v5.0.0): collapse.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

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

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/event-handler.js * Bootstrap (v5.0.0): dom/event-handler.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -22,6 +22,7 @@ const customEvents = {
mouseenter: 'mouseover', mouseenter: 'mouseover',
mouseleave: 'mouseout', mouseleave: 'mouseout',
}; };
const customEventsRegex = /^(mouseenter|mouseleave)/i;
const nativeEvents = new Set([ const nativeEvents = new Set([
'click', 'click',
'dblclick', 'dblclick',
@ -113,7 +114,7 @@ function bootstrapDelegationHandler(element, selector, fn) {
if (handler.oneOff) { if (handler.oneOff) {
// eslint-disable-next-line unicorn/consistent-destructuring // eslint-disable-next-line unicorn/consistent-destructuring
EventHandler.off(element, event.type, fn); EventHandler.off(element, event.type, selector, fn);
} }
return fn.apply(target, [event]); return fn.apply(target, [event]);
@ -144,14 +145,7 @@ function normalizeParams(originalTypeEvent, handler, delegationFn) {
const delegation = typeof handler === 'string'; const delegation = typeof handler === 'string';
const originalHandler = delegation ? delegationFn : handler; const originalHandler = delegation ? delegationFn : handler;
// allow to get the native events from namespaced events ('click.bs.button' --> 'click') let typeEvent = getTypeEvent(originalTypeEvent);
let typeEvent = originalTypeEvent.replace(stripNameRegex, '');
const custom = customEvents[typeEvent];
if (custom) {
typeEvent = custom;
}
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);
if (!isNative) { if (!isNative) {
@ -171,6 +165,28 @@ function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
delegationFn = null; delegationFn = null;
} }
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
if (customEventsRegex.test(originalTypeEvent)) {
const wrapFn = (fn) => {
return function (event) {
if (
!event.relatedTarget ||
(event.relatedTarget !== event.delegateTarget &&
!event.delegateTarget.contains(event.relatedTarget))
) {
return fn.call(this, event);
}
};
};
if (delegationFn) {
delegationFn = wrapFn(delegationFn);
} else {
handler = wrapFn(handler);
}
}
const [delegation, originalHandler, typeEvent] = normalizeParams( const [delegation, originalHandler, typeEvent] = normalizeParams(
originalTypeEvent, originalTypeEvent,
handler, handler,
@ -223,6 +239,12 @@ function removeNamespacedHandlers(element, events, typeEvent, namespace) {
}); });
} }
function getTypeEvent(event) {
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
event = event.replace(stripNameRegex, '');
return customEvents[event] || event;
}
const EventHandler = { const EventHandler = {
on(element, event, handler, delegationFn) { on(element, event, handler, delegationFn) {
addHandler(element, event, handler, delegationFn, false); addHandler(element, event, handler, delegationFn, false);
@ -280,7 +302,7 @@ const EventHandler = {
} }
const $ = getjQuery(); const $ = getjQuery();
const typeEvent = event.replace(stripNameRegex, ''); const typeEvent = getTypeEvent(event);
const inNamespace = event !== typeEvent; const inNamespace = event !== typeEvent;
const isNative = nativeEvents.has(typeEvent); const isNative = nativeEvents.has(typeEvent);

View File

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

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dom/selector-engine.js * Bootstrap (v5.0.0): dom/selector-engine.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): dropdown.js * Bootstrap (v5.0.0): dropdown.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -10,6 +10,7 @@ import * as Popper from '@popperjs/core';
import { import {
defineJQueryPlugin, defineJQueryPlugin,
getElementFromSelector, getElementFromSelector,
isDisabled,
isElement, isElement,
isVisible, isVisible,
isRTL, isRTL,
@ -51,7 +52,6 @@ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_KEYDOWN_DATA_API = `keydown${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}`; const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_DISABLED = 'disabled';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_DROPUP = 'dropup'; const CLASS_NAME_DROPUP = 'dropup';
const CLASS_NAME_DROPEND = 'dropend'; const CLASS_NAME_DROPEND = 'dropend';
@ -76,6 +76,7 @@ const Default = {
reference: 'toggle', reference: 'toggle',
display: 'dynamic', display: 'dynamic',
popperConfig: null, popperConfig: null,
autoClose: true,
}; };
const DefaultType = { const DefaultType = {
@ -84,6 +85,7 @@ const DefaultType = {
reference: '(string|element|object)', reference: '(string|element|object)',
display: 'string', display: 'string',
popperConfig: '(null|object|function)', popperConfig: '(null|object|function)',
autoClose: '(boolean|string)',
}; };
/** /**
@ -121,15 +123,14 @@ class Dropdown extends BaseComponent {
// Public // Public
toggle() { toggle() {
if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) { if (isDisabled(this._element)) {
return; return;
} }
const isActive = this._element.classList.contains(CLASS_NAME_SHOW); const isActive = this._element.classList.contains(CLASS_NAME_SHOW);
Dropdown.clearMenus();
if (isActive) { if (isActive) {
this.hide();
return; return;
} }
@ -137,11 +138,7 @@ class Dropdown extends BaseComponent {
} }
show() { show() {
if ( if (isDisabled(this._element) || this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
@ -198,7 +195,7 @@ class Dropdown extends BaseComponent {
if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) { if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
[] []
.concat(...document.body.children) .concat(...document.body.children)
.forEach((elem) => EventHandler.on(elem, 'mouseover', null, noop())); .forEach((elem) => EventHandler.on(elem, 'mouseover', noop));
} }
this._element.focus(); this._element.focus();
@ -210,11 +207,7 @@ class Dropdown extends BaseComponent {
} }
hide() { hide() {
if ( if (isDisabled(this._element) || !this._menu.classList.contains(CLASS_NAME_SHOW)) {
this._element.disabled ||
this._element.classList.contains(CLASS_NAME_DISABLED) ||
!this._menu.classList.contains(CLASS_NAME_SHOW)
) {
return; return;
} }
@ -222,24 +215,10 @@ class Dropdown extends BaseComponent {
relatedTarget: this._element, relatedTarget: this._element,
}; };
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget); this._completeHide(relatedTarget);
if (hideEvent.defaultPrevented) {
return;
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.toggle(CLASS_NAME_SHOW);
this._element.classList.toggle(CLASS_NAME_SHOW);
Manipulator.removeDataAttribute(this._menu, 'popper');
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
} }
dispose() { dispose() {
EventHandler.off(this._element, EVENT_KEY);
this._menu = null; this._menu = null;
if (this._popper) { if (this._popper) {
@ -266,6 +245,31 @@ class Dropdown extends BaseComponent {
}); });
} }
_completeHide(relatedTarget) {
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE, relatedTarget);
if (hideEvent.defaultPrevented) {
return;
}
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler.off(elem, 'mouseover', noop));
}
if (this._popper) {
this._popper.destroy();
}
this._menu.classList.remove(CLASS_NAME_SHOW);
this._element.classList.remove(CLASS_NAME_SHOW);
this._element.setAttribute('aria-expanded', 'false');
Manipulator.removeDataAttribute(this._menu, 'popper');
EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget);
}
_getConfig(config) { _getConfig(config) {
config = { config = {
...this.constructor.Default, ...this.constructor.Default,
@ -369,6 +373,31 @@ class Dropdown extends BaseComponent {
}; };
} }
_selectMenuItem(event) {
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();
}
// Static // Static
static dropdownInterface(element, config) { static dropdownInterface(element, config) {
@ -403,7 +432,7 @@ class Dropdown extends BaseComponent {
return; return;
} }
if (/input|select|textarea|form/i.test(event.target.tagName)) { if (/input|select|option|textarea|form/i.test(event.target.tagName)) {
return; return;
} }
} }
@ -412,26 +441,26 @@ class Dropdown extends BaseComponent {
for (let i = 0, len = toggles.length; i < len; i++) { for (let i = 0, len = toggles.length; i < len; i++) {
const context = Data.get(toggles[i], DATA_KEY); const context = Data.get(toggles[i], DATA_KEY);
if (!context || context._config.autoClose === false) {
continue;
}
if (!context._element.classList.contains(CLASS_NAME_SHOW)) {
continue;
}
const relatedTarget = { const relatedTarget = {
relatedTarget: toggles[i], relatedTarget: context._element,
}; };
if (event && event.type === 'click') {
relatedTarget.clickEvent = event;
}
if (!context) {
continue;
}
const dropdownMenu = context._menu;
if (!toggles[i].classList.contains(CLASS_NAME_SHOW)) {
continue;
}
if (event) { if (event) {
// Don't close the menu if the clicked element or one of its parents is the dropdown button const composedPath = event.composedPath();
if ([context._element].some((element) => event.composedPath().includes(element))) { const isMenuTarget = composedPath.includes(context._menu);
if (
composedPath.includes(context._element) ||
(context._config.autoClose === 'inside' && !isMenuTarget) ||
(context._config.autoClose === 'outside' && isMenuTarget)
) {
continue; continue;
} }
@ -439,35 +468,17 @@ class Dropdown extends BaseComponent {
if ( if (
event.type === 'keyup' && event.type === 'keyup' &&
event.key === TAB_KEY && event.key === TAB_KEY &&
dropdownMenu.contains(event.target) context._menu.contains(event.target)
) { ) {
continue; continue;
} }
if (event.type === 'click') {
relatedTarget.clickEvent = event;
}
} }
const hideEvent = EventHandler.trigger(toggles[i], EVENT_HIDE, relatedTarget); context._completeHide(relatedTarget);
if (hideEvent.defaultPrevented) {
continue;
}
// If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
[]
.concat(...document.body.children)
.forEach((elem) => EventHandler.off(elem, 'mouseover', null, noop()));
}
toggles[i].setAttribute('aria-expanded', 'false');
if (context._popper) {
context._popper.destroy();
}
dropdownMenu.classList.remove(CLASS_NAME_SHOW);
toggles[i].classList.remove(CLASS_NAME_SHOW);
Manipulator.removeDataAttribute(dropdownMenu, 'popper');
EventHandler.trigger(toggles[i], EVENT_HIDDEN, relatedTarget);
} }
} }
@ -494,30 +505,32 @@ class Dropdown extends BaseComponent {
return; return;
} }
event.preventDefault(); const isActive = this.classList.contains(CLASS_NAME_SHOW);
event.stopPropagation();
if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) { if (!isActive && event.key === ESCAPE_KEY) {
return; return;
} }
const parent = Dropdown.getParentFromElement(this); event.preventDefault();
const isActive = this.classList.contains(CLASS_NAME_SHOW); event.stopPropagation();
if (event.key === ESCAPE_KEY) { if (isDisabled(this)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) return;
}
const getToggleButton = () =>
this.matches(SELECTOR_DATA_TOGGLE)
? this ? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0]; : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
button.focus();
if (event.key === ESCAPE_KEY) {
getToggleButton().focus();
Dropdown.clearMenus(); Dropdown.clearMenus();
return; return;
} }
if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) { if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
const button = this.matches(SELECTOR_DATA_TOGGLE) getToggleButton().click();
? this
: SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE)[0];
button.click();
return; return;
} }
@ -526,28 +539,7 @@ class Dropdown extends BaseComponent {
return; return;
} }
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible); Dropdown.getInstance(getToggleButton())._selectMenuItem(event);
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();
} }
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): modal.js * Bootstrap (v5.0.0): modal.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -10,16 +10,21 @@ import {
emulateTransitionEnd, emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isVisible,
isRTL, isRTL,
isVisible,
reflow, reflow,
typeCheckConfig, typeCheckConfig,
} from './util/index'; } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler'; import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
import {
getWidth as getScrollBarWidth,
hide as scrollBarHide,
reset as scrollBarReset,
} from './util/scrollbar';
import BaseComponent from './base-component'; import BaseComponent from './base-component';
import Backdrop from './util/backdrop';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -58,8 +63,6 @@ const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`;
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`; const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_OPEN = 'modal-open'; const CLASS_NAME_OPEN = 'modal-open';
const CLASS_NAME_FADE = 'fade'; const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
@ -69,8 +72,6 @@ const SELECTOR_DIALOG = '.modal-dialog';
const SELECTOR_MODAL_BODY = '.modal-body'; const SELECTOR_MODAL_BODY = '.modal-body';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]';
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]'; const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -84,12 +85,10 @@ class Modal extends BaseComponent {
this._config = this._getConfig(config); this._config = this._getConfig(config);
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
this._backdrop = null; this._backdrop = this._initializeBackDrop();
this._isShown = false; this._isShown = false;
this._isBodyOverflowing = false;
this._ignoreBackdropClick = false; this._ignoreBackdropClick = false;
this._isTransitioning = false; this._isTransitioning = false;
this._scrollbarWidth = 0;
} }
// Getters // Getters
@ -127,8 +126,9 @@ class Modal extends BaseComponent {
this._isShown = true; this._isShown = true;
this._checkScrollbar(); scrollBarHide();
this._setScrollbar();
document.body.classList.add(CLASS_NAME_OPEN);
this._adjustDialog(); this._adjustDialog();
@ -193,9 +193,7 @@ class Modal extends BaseComponent {
} }
dispose() { dispose() {
[window, this._element, this._dialog].forEach((htmlElement) => [window, this._dialog].forEach((htmlElement) => EventHandler.off(htmlElement, EVENT_KEY));
EventHandler.off(htmlElement, EVENT_KEY)
);
super.dispose(); super.dispose();
@ -208,12 +206,11 @@ class Modal extends BaseComponent {
this._config = null; this._config = null;
this._dialog = null; this._dialog = null;
this._backdrop.dispose();
this._backdrop = null; this._backdrop = null;
this._isShown = null; this._isShown = null;
this._isBodyOverflowing = null;
this._ignoreBackdropClick = null; this._ignoreBackdropClick = null;
this._isTransitioning = null; this._isTransitioning = null;
this._scrollbarWidth = null;
} }
handleUpdate() { handleUpdate() {
@ -222,9 +219,17 @@ class Modal extends BaseComponent {
// Private // Private
_initializeBackDrop() {
return new Backdrop({
isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value
isAnimated: this._isAnimated(),
});
}
_getConfig(config) { _getConfig(config) {
config = { config = {
...Default, ...Default,
...Manipulator.getDataAttributes(this._element),
...config, ...config,
}; };
typeCheckConfig(NAME, config, DefaultType); typeCheckConfig(NAME, config, DefaultType);
@ -323,81 +328,33 @@ class Modal extends BaseComponent {
this._element.removeAttribute('aria-modal'); this._element.removeAttribute('aria-modal');
this._element.removeAttribute('role'); this._element.removeAttribute('role');
this._isTransitioning = false; this._isTransitioning = false;
this._showBackdrop(() => { this._backdrop.hide(() => {
document.body.classList.remove(CLASS_NAME_OPEN); document.body.classList.remove(CLASS_NAME_OPEN);
this._resetAdjustments(); this._resetAdjustments();
this._resetScrollbar(); scrollBarReset();
EventHandler.trigger(this._element, EVENT_HIDDEN); EventHandler.trigger(this._element, EVENT_HIDDEN);
}); });
} }
_removeBackdrop() {
this._backdrop.parentNode.removeChild(this._backdrop);
this._backdrop = null;
}
_showBackdrop(callback) { _showBackdrop(callback) {
const isAnimated = this._isAnimated(); EventHandler.on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._isShown && this._config.backdrop) { if (this._ignoreBackdropClick) {
this._backdrop = document.createElement('div'); this._ignoreBackdropClick = false;
this._backdrop.className = CLASS_NAME_BACKDROP;
if (isAnimated) {
this._backdrop.classList.add(CLASS_NAME_FADE);
}
document.body.appendChild(this._backdrop);
EventHandler.on(this._element, EVENT_CLICK_DISMISS, (event) => {
if (this._ignoreBackdropClick) {
this._ignoreBackdropClick = false;
return;
}
if (event.target !== event.currentTarget) {
return;
}
if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
} else {
this.hide();
}
});
if (isAnimated) {
reflow(this._backdrop);
}
this._backdrop.classList.add(CLASS_NAME_SHOW);
if (!isAnimated) {
callback();
return; return;
} }
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); if (event.target !== event.currentTarget) {
return;
EventHandler.one(this._backdrop, 'transitionend', callback);
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else if (!this._isShown && this._backdrop) {
this._backdrop.classList.remove(CLASS_NAME_SHOW);
const callbackRemove = () => {
this._removeBackdrop();
callback();
};
if (isAnimated) {
const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop);
EventHandler.one(this._backdrop, 'transitionend', callbackRemove);
emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
} else {
callbackRemove();
} }
} else {
callback(); if (this._config.backdrop === true) {
} this.hide();
} else if (this._config.backdrop === 'static') {
this._triggerBackdropTransition();
}
});
this._backdrop.show(callback);
} }
_isAnimated() { _isAnimated() {
@ -438,19 +395,21 @@ class Modal extends BaseComponent {
_adjustDialog() { _adjustDialog() {
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
const scrollbarWidth = getScrollBarWidth();
const isBodyOverflowing = scrollbarWidth > 0;
if ( if (
(!this._isBodyOverflowing && isModalOverflowing && !isRTL()) || (!isBodyOverflowing && isModalOverflowing && !isRTL()) ||
(this._isBodyOverflowing && !isModalOverflowing && isRTL()) (isBodyOverflowing && !isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingLeft = `${this._scrollbarWidth}px`; this._element.style.paddingLeft = `${scrollbarWidth}px`;
} }
if ( if (
(this._isBodyOverflowing && !isModalOverflowing && !isRTL()) || (isBodyOverflowing && !isModalOverflowing && !isRTL()) ||
(!this._isBodyOverflowing && isModalOverflowing && isRTL()) (!isBodyOverflowing && isModalOverflowing && isRTL())
) { ) {
this._element.style.paddingRight = `${this._scrollbarWidth}px`; this._element.style.paddingRight = `${scrollbarWidth}px`;
} }
} }
@ -459,100 +418,22 @@ class Modal extends BaseComponent {
this._element.style.paddingRight = ''; this._element.style.paddingRight = '';
} }
_checkScrollbar() {
const rect = document.body.getBoundingClientRect();
this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
this._scrollbarWidth = this._getScrollbarWidth();
}
_setScrollbar() {
if (this._isBodyOverflowing) {
this._setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
this._setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - this._scrollbarWidth
);
this._setElementAttributes(
'body',
'paddingRight',
(calculatedValue) => calculatedValue + this._scrollbarWidth
);
}
document.body.classList.add(CLASS_NAME_OPEN);
}
_setElementAttributes(selector, styleProp, callback) {
SelectorEngine.find(selector).forEach((element) => {
if (
element !== document.body &&
window.innerWidth > element.clientWidth + this._scrollbarWidth
) {
return;
}
const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px';
});
}
_resetScrollbar() {
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
this._resetElementAttributes('body', 'paddingRight');
}
_resetElementAttributes(selector, styleProp) {
SelectorEngine.find(selector).forEach((element) => {
const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) {
element.style[styleProp] = '';
} else {
Manipulator.removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
}
_getScrollbarWidth() {
// thx d.walsh
const scrollDiv = document.createElement('div');
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
document.body.appendChild(scrollDiv);
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
document.body.removeChild(scrollDiv);
return scrollbarWidth;
}
// Static // Static
static jQueryInterface(config, relatedTarget) { static jQueryInterface(config, relatedTarget) {
return this.each(function () { return this.each(function () {
let data = Data.get(this, DATA_KEY); const data =
const _config = { Modal.getInstance(this) || new Modal(this, typeof config === 'object' ? config : {});
...Default,
...Manipulator.getDataAttributes(this),
...(typeof config === 'object' && config ? config : {}),
};
if (!data) { if (typeof config !== 'string') {
data = new Modal(this, _config); return;
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config](relatedTarget);
} }
data[config](relatedTarget);
}); });
} }
} }
@ -566,7 +447,7 @@ class Modal extends BaseComponent {
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
const target = getElementFromSelector(this); const target = getElementFromSelector(this);
if (this.tagName === 'A' || this.tagName === 'AREA') { if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault(); event.preventDefault();
} }
@ -583,15 +464,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
}); });
}); });
let data = Data.get(target, DATA_KEY); const data = Modal.getInstance(target) || new Modal(target);
if (!data) {
const config = {
...Manipulator.getDataAttributes(target),
...Manipulator.getDataAttributes(this),
};
data = new Modal(target, config);
}
data.toggle(this); data.toggle(this);
}); });

View File

@ -1,14 +1,14 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): offcanvas.js * Bootstrap (v5.0.0): offcanvas.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
import { import {
defineJQueryPlugin, defineJQueryPlugin,
emulateTransitionEnd,
getElementFromSelector, getElementFromSelector,
getSelectorFromElement,
getTransitionDurationFromElement, getTransitionDurationFromElement,
isDisabled, isDisabled,
isVisible, isVisible,
@ -20,6 +20,7 @@ import EventHandler from './dom/event-handler';
import BaseComponent from './base-component'; import BaseComponent from './base-component';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import Backdrop from './util/backdrop';
/** /**
* ------------------------------------------------------------------------ * ------------------------------------------------------------------------
@ -46,11 +47,8 @@ const DefaultType = {
scroll: 'boolean', scroll: 'boolean',
}; };
const CLASS_NAME_BACKDROP_BODY = 'offcanvas-backdrop';
const CLASS_NAME_SHOW = 'show'; const CLASS_NAME_SHOW = 'show';
const CLASS_NAME_TOGGLING = 'offcanvas-toggling';
const OPEN_SELECTOR = '.offcanvas.show'; const OPEN_SELECTOR = '.offcanvas.show';
const ACTIVE_SELECTOR = `${OPEN_SELECTOR}, .${CLASS_NAME_TOGGLING}`;
const EVENT_SHOW = `show${EVENT_KEY}`; const EVENT_SHOW = `show${EVENT_KEY}`;
const EVENT_SHOWN = `shown${EVENT_KEY}`; const EVENT_SHOWN = `shown${EVENT_KEY}`;
@ -59,6 +57,7 @@ const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`; const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_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_DISMISS = '[data-bs-dismiss="offcanvas"]';
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]'; const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
@ -75,6 +74,7 @@ class Offcanvas extends BaseComponent {
this._config = this._getConfig(config); this._config = this._getConfig(config);
this._isShown = false; this._isShown = false;
this._backdrop = this._initializeBackDrop();
this._addEventListeners(); this._addEventListeners();
} }
@ -108,27 +108,25 @@ class Offcanvas extends BaseComponent {
this._isShown = true; this._isShown = true;
this._element.style.visibility = 'visible'; this._element.style.visibility = 'visible';
if (this._config.backdrop) { this._backdrop.show();
document.body.classList.add(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarHide(); scrollBarHide();
this._enforceFocusOnElement(this._element);
} }
this._element.classList.add(CLASS_NAME_TOGGLING);
this._element.removeAttribute('aria-hidden'); this._element.removeAttribute('aria-hidden');
this._element.setAttribute('aria-modal', true); this._element.setAttribute('aria-modal', true);
this._element.setAttribute('role', 'dialog'); this._element.setAttribute('role', 'dialog');
this._element.classList.add(CLASS_NAME_SHOW); this._element.classList.add(CLASS_NAME_SHOW);
const completeCallBack = () => { const completeCallBack = () => {
this._element.classList.remove(CLASS_NAME_TOGGLING);
EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget }); EventHandler.trigger(this._element, EVENT_SHOWN, { relatedTarget });
this._enforceFocusOnElement(this._element);
}; };
setTimeout(completeCallBack, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler.one(this._element, 'transitionend', completeCallBack);
emulateTransitionEnd(this._element, transitionDuration);
} }
hide() { hide() {
@ -142,11 +140,11 @@ class Offcanvas extends BaseComponent {
return; return;
} }
this._element.classList.add(CLASS_NAME_TOGGLING);
EventHandler.off(document, EVENT_FOCUSIN); EventHandler.off(document, EVENT_FOCUSIN);
this._element.blur(); this._element.blur();
this._isShown = false; this._isShown = false;
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
this._backdrop.hide();
const completeCallback = () => { const completeCallback = () => {
this._element.setAttribute('aria-hidden', true); this._element.setAttribute('aria-hidden', true);
@ -154,19 +152,25 @@ class Offcanvas extends BaseComponent {
this._element.removeAttribute('role'); this._element.removeAttribute('role');
this._element.style.visibility = 'hidden'; this._element.style.visibility = 'hidden';
if (this._config.backdrop) {
document.body.classList.remove(CLASS_NAME_BACKDROP_BODY);
}
if (!this._config.scroll) { if (!this._config.scroll) {
scrollBarReset(); scrollBarReset();
} }
EventHandler.trigger(this._element, EVENT_HIDDEN); EventHandler.trigger(this._element, EVENT_HIDDEN);
this._element.classList.remove(CLASS_NAME_TOGGLING);
}; };
setTimeout(completeCallback, getTransitionDurationFromElement(this._element)); const transitionDuration = getTransitionDurationFromElement(this._element);
EventHandler.one(this._element, 'transitionend', completeCallback);
emulateTransitionEnd(this._element, transitionDuration);
}
dispose() {
this._backdrop.dispose();
super.dispose();
EventHandler.off(document, EVENT_FOCUSIN);
this._config = null;
this._backdrop = null;
} }
// Private // Private
@ -181,6 +185,15 @@ class Offcanvas extends BaseComponent {
return config; return config;
} }
_initializeBackDrop() {
return new Backdrop({
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,
clickCallback: () => this.hide(),
});
}
_enforceFocusOnElement(element) { _enforceFocusOnElement(element) {
EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
EventHandler.on(document, EVENT_FOCUSIN, (event) => { EventHandler.on(document, EVENT_FOCUSIN, (event) => {
@ -198,18 +211,11 @@ class Offcanvas extends BaseComponent {
_addEventListeners() { _addEventListeners() {
EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide()); EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
EventHandler.on(document, 'keydown', (event) => { EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, (event) => {
if (this._config.keyboard && event.key === ESCAPE_KEY) { if (this._config.keyboard && event.key === ESCAPE_KEY) {
this.hide(); this.hide();
} }
}); });
EventHandler.on(document, EVENT_CLICK_DATA_API, (event) => {
const target = SelectorEngine.findOne(getSelectorFromElement(event.target));
if (!this._element.contains(event.target) && target !== this._element) {
this.hide();
}
});
} }
// Static // Static
@ -257,9 +263,9 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
}); });
// avoid conflict when clicking a toggler of an offcanvas, while another is open // avoid conflict when clicking a toggler of an offcanvas, while another is open
const allReadyOpen = SelectorEngine.findOne(ACTIVE_SELECTOR); const allReadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
if (allReadyOpen && allReadyOpen !== target) { if (allReadyOpen && allReadyOpen !== target) {
return; Offcanvas.getInstance(allReadyOpen).hide();
} }
const data = Data.get(target, DATA_KEY) || new Offcanvas(target); const data = Data.get(target, DATA_KEY) || new Offcanvas(target);

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): popover.js * Bootstrap (v5.0.0): popover.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): scrollspy.js * Bootstrap (v5.0.0): scrollspy.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -12,7 +12,6 @@ import {
isElement, isElement,
typeCheckConfig, typeCheckConfig,
} from './util/index'; } from './util/index';
import Data from './dom/data';
import EventHandler from './dom/event-handler'; import EventHandler from './dom/event-handler';
import Manipulator from './dom/manipulator'; import Manipulator from './dom/manipulator';
import SelectorEngine from './dom/selector-engine'; import SelectorEngine from './dom/selector-engine';
@ -148,6 +147,7 @@ class ScrollSpy extends BaseComponent {
_getConfig(config) { _getConfig(config) {
config = { config = {
...Default, ...Default,
...Manipulator.getDataAttributes(this._element),
...(typeof config === 'object' && config ? config : {}), ...(typeof config === 'object' && config ? config : {}),
}; };
@ -276,20 +276,19 @@ class ScrollSpy extends BaseComponent {
static jQueryInterface(config) { static jQueryInterface(config) {
return this.each(function () { return this.each(function () {
let data = Data.get(this, DATA_KEY); const data =
const _config = typeof config === 'object' && config; ScrollSpy.getInstance(this) ||
new ScrollSpy(this, typeof config === 'object' ? config : {});
if (!data) { if (typeof config !== 'string') {
data = new ScrollSpy(this, _config); return;
} }
if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
if (typeof data[config] === 'undefined') { throw new TypeError(`No method named "${config}"`);
throw new TypeError(`No method named "${config}"`);
}
data[config]();
} }
data[config]();
}); });
} }
} }
@ -301,9 +300,7 @@ class ScrollSpy extends BaseComponent {
*/ */
EventHandler.on(window, EVENT_LOAD_DATA_API, () => { EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
SelectorEngine.find(SELECTOR_DATA_SPY).forEach( SelectorEngine.find(SELECTOR_DATA_SPY).forEach((spy) => new ScrollSpy(spy));
(spy) => new ScrollSpy(spy, Manipulator.getDataAttributes(spy))
);
}); });
/** /**

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tab.js * Bootstrap (v5.0.0): tab.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -66,10 +66,9 @@ class Tab extends BaseComponent {
show() { show() {
if ( if (
(this._element.parentNode && this._element.parentNode &&
this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
this._element.classList.contains(CLASS_NAME_ACTIVE)) || this._element.classList.contains(CLASS_NAME_ACTIVE)
isDisabled(this._element)
) { ) {
return; return;
} }
@ -172,11 +171,16 @@ class Tab extends BaseComponent {
element.classList.add(CLASS_NAME_SHOW); element.classList.add(CLASS_NAME_SHOW);
} }
if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) { let parent = element.parentNode;
if (parent && parent.nodeName === 'LI') {
parent = parent.parentNode;
}
if (parent && parent.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
const dropdownElement = element.closest(SELECTOR_DROPDOWN); const dropdownElement = element.closest(SELECTOR_DROPDOWN);
if (dropdownElement) { if (dropdownElement) {
SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE).forEach((dropdown) => SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE, dropdownElement).forEach((dropdown) =>
dropdown.classList.add(CLASS_NAME_ACTIVE) dropdown.classList.add(CLASS_NAME_ACTIVE)
); );
} }
@ -213,7 +217,13 @@ class Tab extends BaseComponent {
*/ */
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault(); if (['A', 'AREA'].includes(this.tagName)) {
event.preventDefault();
}
if (isDisabled(this)) {
return;
}
const data = Data.get(this, DATA_KEY) || new Tab(this); const data = Data.get(this, DATA_KEY) || new Tab(this);
data.show(); data.show();

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): toast.js * Bootstrap (v5.0.0): toast.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -156,8 +156,6 @@ class Toast extends BaseComponent {
this._element.classList.remove(CLASS_NAME_SHOW); this._element.classList.remove(CLASS_NAME_SHOW);
} }
EventHandler.off(this._element, EVENT_CLICK_DISMISS);
super.dispose(); super.dispose();
this._config = null; this._config = null;
} }

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): tooltip.js * Bootstrap (v5.0.0): tooltip.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -213,7 +213,6 @@ class Tooltip extends BaseComponent {
dispose() { dispose() {
clearTimeout(this._timeout); clearTimeout(this._timeout);
EventHandler.off(this._element, this.constructor.EVENT_KEY);
EventHandler.off( EventHandler.off(
this._element.closest(`.${CLASS_NAME_MODAL}`), this._element.closest(`.${CLASS_NAME_MODAL}`),
'hide.bs.modal', 'hide.bs.modal',
@ -308,7 +307,7 @@ class Tooltip extends BaseComponent {
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement) { if ('ontouchstart' in document.documentElement) {
[].concat(...document.body.children).forEach((element) => { [].concat(...document.body.children).forEach((element) => {
EventHandler.on(element, 'mouseover', noop()); EventHandler.on(element, 'mouseover', noop);
}); });
} }
@ -512,7 +511,6 @@ class Tooltip extends BaseComponent {
{ {
name: 'flip', name: 'flip',
options: { options: {
altBoundary: true,
fallbackPlacements: this.config.fallbackPlacements, fallbackPlacements: this.config.fallbackPlacements,
}, },
}, },

View File

@ -0,0 +1,139 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): util/backdrop.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
import EventHandler from '../dom/event-handler';
import {
emulateTransitionEnd,
execute,
getTransitionDurationFromElement,
reflow,
typeCheckConfig,
} from './index';
const Default = {
isVisible: true, // if false, we use the backdrop helper without adding any element to the dom
isAnimated: false,
rootElement: document.body, // give the choice to place backdrop under different elements
clickCallback: null,
};
const DefaultType = {
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: 'element',
clickCallback: '(function|null)',
};
const NAME = 'backdrop';
const CLASS_NAME_BACKDROP = 'modal-backdrop';
const CLASS_NAME_FADE = 'fade';
const CLASS_NAME_SHOW = 'show';
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`;
class Backdrop {
constructor(config) {
this._config = this._getConfig(config);
this._isAppended = false;
this._element = null;
}
show(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._append();
if (this._config.isAnimated) {
reflow(this._getElement());
}
this._getElement().classList.add(CLASS_NAME_SHOW);
this._emulateAnimation(() => {
execute(callback);
});
}
hide(callback) {
if (!this._config.isVisible) {
execute(callback);
return;
}
this._getElement().classList.remove(CLASS_NAME_SHOW);
this._emulateAnimation(() => {
this.dispose();
execute(callback);
});
}
// Private
_getElement() {
if (!this._element) {
const backdrop = document.createElement('div');
backdrop.className = CLASS_NAME_BACKDROP;
if (this._config.isAnimated) {
backdrop.classList.add(CLASS_NAME_FADE);
}
this._element = backdrop;
}
return this._element;
}
_getConfig(config) {
config = {
...Default,
...(typeof config === 'object' ? config : {}),
};
typeCheckConfig(NAME, config, DefaultType);
return config;
}
_append() {
if (this._isAppended) {
return;
}
this._config.rootElement.appendChild(this._getElement());
EventHandler.on(this._getElement(), EVENT_MOUSEDOWN, () => {
execute(this._config.clickCallback);
});
this._isAppended = true;
}
dispose() {
if (!this._isAppended) {
return;
}
EventHandler.off(this._element, EVENT_MOUSEDOWN);
this._getElement().parentNode.removeChild(this._element);
this._isAppended = false;
}
_emulateAnimation(callback) {
if (!this._config.isAnimated) {
execute(callback);
return;
}
const backdropTransitionDuration = getTransitionDurationFromElement(this._getElement());
EventHandler.one(this._getElement(), 'transitionend', () => execute(callback));
emulateTransitionEnd(this._getElement(), backdropTransitionDuration);
}
}
export default Backdrop;

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/index.js * Bootstrap (v5.0.0): util/index.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -51,7 +51,7 @@ const getSelector = (element) => {
// Just in case some CMS puts out a full URL with the anchor appended // Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) { if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
hrefAttr = '#' + hrefAttr.split('#')[1]; hrefAttr = `#${hrefAttr.split('#')[1]}`;
} }
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null; selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
@ -134,9 +134,7 @@ const typeCheckConfig = (componentName, config, configTypes) => {
if (!new RegExp(expectedTypes).test(valueType)) { if (!new RegExp(expectedTypes).test(valueType)) {
throw new TypeError( throw new TypeError(
`${componentName.toUpperCase()}: ` + `${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`
`Option "${property}" provided type "${valueType}" ` +
`but expected type "${expectedTypes}".`
); );
} }
}); });
@ -200,7 +198,7 @@ const findShadowRoot = (element) => {
return findShadowRoot(element.parentNode); return findShadowRoot(element.parentNode);
}; };
const noop = () => function () {}; const noop = () => {};
const reflow = (element) => element.offsetHeight; const reflow = (element) => element.offsetHeight;
@ -240,6 +238,12 @@ const defineJQueryPlugin = (name, plugin) => {
}); });
}; };
const execute = (callback) => {
if (typeof callback === 'function') {
callback();
}
};
export { export {
getUID, getUID,
getSelectorFromElement, getSelectorFromElement,
@ -258,4 +262,5 @@ export {
onDOMContentLoaded, onDOMContentLoaded,
isRTL, isRTL,
defineJQueryPlugin, defineJQueryPlugin,
execute,
}; };

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/sanitizer.js * Bootstrap (v5.0.0): util/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta3): util/scrollBar.js * Bootstrap (v5.0.0): util/scrollBar.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- * --------------------------------------------------------------------------
*/ */
@ -8,7 +8,7 @@
import SelectorEngine from '../dom/selector-engine'; import SelectorEngine from '../dom/selector-engine';
import Manipulator from '../dom/manipulator'; import Manipulator from '../dom/manipulator';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed'; const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top'; const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => { const getWidth = () => {
@ -18,7 +18,10 @@ const getWidth = () => {
}; };
const hide = (width = getWidth()) => { const hide = (width = getWidth()) => {
document.body.style.overflow = 'hidden'; _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( _setElementAttributes(
SELECTOR_FIXED_CONTENT, SELECTOR_FIXED_CONTENT,
'paddingRight', 'paddingRight',
@ -29,7 +32,15 @@ const hide = (width = getWidth()) => {
'marginRight', 'marginRight',
(calculatedValue) => calculatedValue - width (calculatedValue) => calculatedValue - width
); );
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width); };
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.style.overflow = 'hidden';
}; };
const _setElementAttributes = (selector, styleProp, callback) => { const _setElementAttributes = (selector, styleProp, callback) => {
@ -42,21 +53,21 @@ const _setElementAttributes = (selector, styleProp, callback) => {
const actualValue = element.style[styleProp]; const actualValue = element.style[styleProp];
const calculatedValue = window.getComputedStyle(element)[styleProp]; const calculatedValue = window.getComputedStyle(element)[styleProp];
Manipulator.setDataAttribute(element, styleProp, actualValue); Manipulator.setDataAttribute(element, styleProp, actualValue);
element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px'; element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
}); });
}; };
const reset = () => { const reset = () => {
document.body.style.overflow = 'auto'; _resetElementAttributes('body', 'overflow');
_resetElementAttributes('body', 'paddingRight');
_resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight'); _resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
_resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight'); _resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
_resetElementAttributes('body', 'paddingRight');
}; };
const _resetElementAttributes = (selector, styleProp) => { const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach((element) => { SelectorEngine.find(selector).forEach((element) => {
const value = Manipulator.getDataAttribute(element, styleProp); const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined' && element === document.body) { if (typeof value === 'undefined') {
element.style.removeProperty(styleProp); element.style.removeProperty(styleProp);
} else { } else {
Manipulator.removeDataAttribute(element, styleProp); Manipulator.removeDataAttribute(element, styleProp);

View File

@ -147,6 +147,10 @@ class Input {
} }
_showCounter() { _showCounter() {
const counters = SelectorEngine.find('.form-counter', this._element);
if (counters.length > 0) {
return;
}
this._counterElement = document.createElement('div'); this._counterElement = document.createElement('div');
Manipulator.addClass(this._counterElement, CLASSNAME_COUNTER); Manipulator.addClass(this._counterElement, CLASSNAME_COUNTER);
const actualLength = this.input.value.length; const actualLength = this.input.value.length;

View File

@ -0,0 +1,83 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0): 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';
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
const SELECTOR_STICKY_CONTENT = '.sticky-top';
const getWidth = () => {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
const documentWidth = document.documentElement.clientWidth;
return Math.abs(window.innerWidth - documentWidth);
};
const hide = (width = getWidth()) => {
_disableOverFlow();
// give padding to element to balances the hidden scrollbar width
_setElementAttributes('body', 'paddingRight', (calculatedValue) => calculatedValue + width);
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements, to keep shown fullwidth
_setElementAttributes(
SELECTOR_FIXED_CONTENT,
'paddingRight',
(calculatedValue) => calculatedValue + width
);
_setElementAttributes(
SELECTOR_STICKY_CONTENT,
'marginRight',
(calculatedValue) => calculatedValue - width
);
};
const _disableOverFlow = () => {
const actualValue = document.body.style.overflow;
if (actualValue) {
Manipulator.setDataAttribute(document.body, 'overflow', actualValue);
}
document.body.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) {
return;
}
const actualValue = element.style[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');
};
const _resetElementAttributes = (selector, styleProp) => {
SelectorEngine.find(selector).forEach((element) => {
const value = Manipulator.getDataAttribute(element, styleProp);
if (typeof value === 'undefined') {
element.style.removeProperty(styleProp);
} else {
Manipulator.removeDataAttribute(element, styleProp);
element.style[styleProp] = value;
}
});
};
const isBodyOverflowing = () => {
return getWidth() > 0;
};
export { getWidth, hide, isBodyOverflowing, reset };

View File

@ -58,7 +58,6 @@
} }
.accordion-item { .accordion-item {
margin-bottom: -$accordion-border-width;
background-color: $accordion-bg; background-color: $accordion-bg;
border: $accordion-border-width solid $accordion-border-color; border: $accordion-border-width solid $accordion-border-color;
@ -70,9 +69,12 @@
} }
} }
&:not(:first-of-type) {
border-top: 0;
}
// Only set a border-radius on the last item if the accordion is collapsed // Only set a border-radius on the last item if the accordion is collapsed
&:last-of-type { &:last-of-type {
margin-bottom: 0;
@include border-bottom-radius($accordion-border-radius); @include border-bottom-radius($accordion-border-radius);
.accordion-button { .accordion-button {

View File

@ -141,14 +141,14 @@
background-size: 100% 100%; background-size: 100% 100%;
} }
/*!rtl:options: { /*!rtl:options:{
"autoRename": true, "autoRename": true,
"stringMap":[ { "stringMap":[ {
"name" : "prev-next", "name" : "prev-next",
"search" : "prev", "search" : "prev",
"replace" : "next" "replace" : "next"
} ] } ]
} */ }*/
.carousel-control-prev-icon { .carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg); background-image: escape-svg($carousel-control-prev-icon-bg);
} }

View File

@ -16,7 +16,6 @@
// The dropdown menu // The dropdown menu
.dropdown-menu { .dropdown-menu {
position: absolute; position: absolute;
top: 100%;
z-index: $zindex-dropdown; z-index: $zindex-dropdown;
display: none; // none by default, but block on "open" of the menu display: none; // none by default, but block on "open" of the menu
min-width: $dropdown-min-width; min-width: $dropdown-min-width;
@ -33,6 +32,7 @@
@include box-shadow($dropdown-box-shadow); @include box-shadow($dropdown-box-shadow);
&[data-mdb-popper] { &[data-mdb-popper] {
top: 100%;
left: 0; left: 0;
margin-top: $dropdown-spacer; margin-top: $dropdown-spacer;
} }
@ -87,15 +87,12 @@
} }
.dropend { .dropend {
.dropdown-menu { .dropdown-menu[data-mdb-popper] {
top: 0; top: 0;
right: auto; right: auto;
left: 100%; left: 100%;
margin-top: 0;
&[data-mdb-popper] { margin-left: $dropdown-spacer;
margin-top: 0;
margin-left: $dropdown-spacer;
}
} }
.dropdown-toggle { .dropdown-toggle {
@ -107,15 +104,12 @@
} }
.dropstart { .dropstart {
.dropdown-menu { .dropdown-menu[data-mdb-popper] {
top: 0; top: 0;
right: 100%; right: 100%;
left: auto; left: auto;
margin-top: 0;
&[data-mdb-popper] { margin-right: $dropdown-spacer;
margin-top: 0;
margin-right: $dropdown-spacer;
}
} }
.dropdown-toggle { .dropdown-toggle {

View File

@ -161,7 +161,11 @@
$list-group-background: shift-color($value, $list-group-item-bg-scale); $list-group-background: shift-color($value, $list-group-item-bg-scale);
$list-group-color: shift-color($value, $list-group-item-color-scale); $list-group-color: shift-color($value, $list-group-item-color-scale);
@if (contrast-ratio($list-group-background, $list-group-color) < $min-contrast-ratio) { @if (contrast-ratio($list-group-background, $list-group-color) < $min-contrast-ratio) {
$list-group-color: mix($value, color-contrast($list-group-background), abs($alert-color-scale)); $list-group-color: mix(
$value,
color-contrast($list-group-background),
abs($list-group-item-color-scale)
);
} }
@include list-group-item-variant($state, $list-group-background, $list-group-color); @include list-group-item-variant($state, $list-group-background, $list-group-color);

View File

@ -10,6 +10,7 @@
// Helpers // Helpers
@import 'mixins/breakpoints'; @import 'mixins/breakpoints';
@import 'mixins/color-scheme';
@import 'mixins/image'; @import 'mixins/image';
@import 'mixins/resize'; @import 'mixins/resize';
@import 'mixins/visually-hidden'; @import 'mixins/visually-hidden';

View File

@ -163,15 +163,6 @@
} }
} }
// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
// Scale up the modal // Scale up the modal
@include media-breakpoint-up(sm) { @include media-breakpoint-up(sm) {
// Automatically set modal's width for larger viewports // Automatically set modal's width for larger viewports

View File

@ -16,6 +16,7 @@
.offcanvas-header { .offcanvas-header {
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
padding: $offcanvas-padding-y $offcanvas-padding-x; padding: $offcanvas-padding-y $offcanvas-padding-x;
@ -52,6 +53,16 @@
transform: translateX(100%); transform: translateX(100%);
} }
.offcanvas-top {
top: 0;
right: 0;
left: 0;
height: $offcanvas-vertical-height;
max-height: 100%;
border-bottom: $offcanvas-border-width solid $offcanvas-border-color;
transform: translateY(-100%);
}
.offcanvas-bottom { .offcanvas-bottom {
right: 0; right: 0;
left: 0; left: 0;
@ -64,14 +75,3 @@
.offcanvas.show { .offcanvas.show {
transform: none; transform: none;
} }
.offcanvas-backdrop::before {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-offcanvas - 1;
width: 100vw;
height: 100vh;
content: '';
background-color: $offcanvas-body-backdrop-color;
}

View File

@ -15,7 +15,7 @@
display: inline-block; display: inline-block;
width: $spinner-width; width: $spinner-width;
height: $spinner-height; height: $spinner-height;
vertical-align: text-bottom; vertical-align: $spinner-vertical-align;
border: $spinner-border-width solid currentColor; border: $spinner-border-width solid currentColor;
border-right-color: transparent; border-right-color: transparent;
// stylelint-disable-next-line property-disallowed-list // stylelint-disable-next-line property-disallowed-list
@ -49,7 +49,7 @@
display: inline-block; display: inline-block;
width: $spinner-width; width: $spinner-width;
height: $spinner-height; height: $spinner-height;
vertical-align: text-bottom; vertical-align: $spinner-vertical-align;
background-color: currentColor; background-color: currentColor;
// stylelint-disable-next-line property-disallowed-list // stylelint-disable-next-line property-disallowed-list
border-radius: 50%; border-radius: 50%;

View File

@ -742,7 +742,7 @@ $form-check-transition: null !default;
$form-check-input-active-filter: brightness(90%) !default; $form-check-input-active-filter: brightness(90%) !default;
$form-check-input-bg: $input-bg !default; $form-check-input-bg: $input-bg !default;
$form-check-input-border: 1px solid rgba(0, 0, 0, 0.25) !default; $form-check-input-border: 1px solid rgba($black, 0.25) !default;
$form-check-input-border-radius: 0.25em !default; $form-check-input-border-radius: 0.25em !default;
$form-check-radio-border-radius: 50% !default; $form-check-radio-border-radius: 50% !default;
$form-check-input-focus-border: $input-focus-border-color !default; $form-check-input-focus-border: $input-focus-border-color !default;
@ -908,8 +908,8 @@ $form-validation-states: (
$zindex-dropdown: 1000 !default; $zindex-dropdown: 1000 !default;
$zindex-sticky: 1020 !default; $zindex-sticky: 1020 !default;
$zindex-fixed: 1030 !default; $zindex-fixed: 1030 !default;
$zindex-offcanvas: 1040 !default; $zindex-modal-backdrop: 1040 !default;
$zindex-modal-backdrop: 1050 !default; $zindex-offcanvas: 1050 !default;
$zindex-modal: 1060 !default; $zindex-modal: 1060 !default;
$zindex-popover: 1070 !default; $zindex-popover: 1070 !default;
$zindex-tooltip: 1080 !default; $zindex-tooltip: 1080 !default;
@ -922,8 +922,8 @@ $nav-link-padding-y: 0.5rem !default;
$nav-link-padding-x: 1rem !default; $nav-link-padding-x: 1rem !default;
$nav-link-font-size: null !default; $nav-link-font-size: null !default;
$nav-link-font-weight: null !default; $nav-link-font-weight: null !default;
$nav-link-color: null !default; $nav-link-color: $link-color !default;
$nav-link-hover-color: null !default; $nav-link-hover-color: $link-hover-color !default;
$nav-link-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, $nav-link-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
border-color 0.15s ease-in-out !default; border-color 0.15s ease-in-out !default;
$nav-link-disabled-color: $gray-600 !default; $nav-link-disabled-color: $gray-600 !default;
@ -1131,7 +1131,7 @@ $accordion-icon-width: 1.25rem !default;
$accordion-icon-color: $accordion-color !default; $accordion-icon-color: $accordion-color !default;
$accordion-icon-active-color: $accordion-button-active-color !default; $accordion-icon-active-color: $accordion-button-active-color !default;
$accordion-icon-transition: transform 0.2s ease-in-out !default; $accordion-icon-transition: transform 0.2s ease-in-out !default;
$accordion-icon-transform: rotate(180deg) !default; $accordion-icon-transform: rotate(-180deg) !default;
$accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; $accordion-button-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
$accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default; $accordion-button-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='#{$accordion-icon-active-color}'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>") !default;
@ -1404,6 +1404,7 @@ $carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;
// scss-docs-start spinner-variables // scss-docs-start spinner-variables
$spinner-width: 2rem !default; $spinner-width: 2rem !default;
$spinner-height: $spinner-width !default; $spinner-height: $spinner-width !default;
$spinner-vertical-align: -0.125em !default;
$spinner-border-width: 0.25em !default; $spinner-border-width: 0.25em !default;
$spinner-animation-speed: 0.75s !default; $spinner-animation-speed: 0.75s !default;
@ -1442,7 +1443,6 @@ $offcanvas-border-width: $modal-content-border-width !default;
$offcanvas-title-line-height: $modal-title-line-height !default; $offcanvas-title-line-height: $modal-title-line-height !default;
$offcanvas-bg-color: $modal-content-bg !default; $offcanvas-bg-color: $modal-content-bg !default;
$offcanvas-color: $modal-content-color !default; $offcanvas-color: $modal-content-color !default;
$offcanvas-body-backdrop-color: rgba($modal-backdrop-bg, $modal-backdrop-opacity) !default;
$offcanvas-box-shadow: $modal-content-box-shadow-xs !default; $offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
// scss-docs-end offcanvas-variables // scss-docs-end offcanvas-variables

View File

@ -1,5 +1,5 @@
/*! /*!
* Bootstrap Grid v5.0.0-beta3 (https://getbootstrap.com/) * Bootstrap Grid v5.0.0 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 The Bootstrap Authors
* Copyright 2011-2021 Twitter, Inc. * Copyright 2011-2021 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)

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