bootstrap 5.1.1 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/assets/javascripts/bootstrap/alert.js +18 -153
  4. data/assets/javascripts/bootstrap/base-component.js +44 -127
  5. data/assets/javascripts/bootstrap/button.js +16 -80
  6. data/assets/javascripts/bootstrap/carousel.js +225 -497
  7. data/assets/javascripts/bootstrap/collapse.js +79 -262
  8. data/assets/javascripts/bootstrap/dom/data.js +6 -8
  9. data/assets/javascripts/bootstrap/dom/event-handler.js +95 -133
  10. data/assets/javascripts/bootstrap/dom/manipulator.js +25 -29
  11. data/assets/javascripts/bootstrap/dom/selector-engine.js +17 -59
  12. data/assets/javascripts/bootstrap/dropdown.js +124 -342
  13. data/assets/javascripts/bootstrap/modal.js +122 -767
  14. data/assets/javascripts/bootstrap/offcanvas.js +102 -671
  15. data/assets/javascripts/bootstrap/popover.js +42 -124
  16. data/assets/javascripts/bootstrap/scrollspy.js +186 -269
  17. data/assets/javascripts/bootstrap/tab.js +222 -221
  18. data/assets/javascripts/bootstrap/toast.js +41 -227
  19. data/assets/javascripts/bootstrap/tooltip.js +283 -629
  20. data/assets/javascripts/bootstrap/util/backdrop.js +165 -0
  21. data/assets/javascripts/bootstrap/util/component-functions.js +46 -0
  22. data/assets/javascripts/bootstrap/util/config.js +79 -0
  23. data/assets/javascripts/bootstrap/util/focustrap.js +129 -0
  24. data/assets/javascripts/bootstrap/util/index.js +350 -0
  25. data/assets/javascripts/bootstrap/util/sanitizer.js +122 -0
  26. data/assets/javascripts/bootstrap/util/scrollbar.js +138 -0
  27. data/assets/javascripts/bootstrap/util/swipe.js +155 -0
  28. data/assets/javascripts/bootstrap/util/template-factory.js +177 -0
  29. data/assets/javascripts/bootstrap-global-this-define.js +1 -1
  30. data/assets/javascripts/bootstrap-sprockets.js +16 -7
  31. data/assets/javascripts/bootstrap.js +2094 -1891
  32. data/assets/javascripts/bootstrap.min.js +3 -3
  33. data/assets/stylesheets/_bootstrap-grid.scss +3 -6
  34. data/assets/stylesheets/_bootstrap-reboot.scss +3 -7
  35. data/assets/stylesheets/_bootstrap.scss +4 -6
  36. data/assets/stylesheets/bootstrap/_accordion.scss +52 -24
  37. data/assets/stylesheets/bootstrap/_alert.scss +18 -4
  38. data/assets/stylesheets/bootstrap/_badge.scss +14 -5
  39. data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
  40. data/assets/stylesheets/bootstrap/_button-group.scss +3 -0
  41. data/assets/stylesheets/bootstrap/_buttons.scss +97 -22
  42. data/assets/stylesheets/bootstrap/_card.scss +55 -37
  43. data/assets/stylesheets/bootstrap/_close.scss +1 -1
  44. data/assets/stylesheets/bootstrap/_containers.scss +1 -1
  45. data/assets/stylesheets/bootstrap/_dropdown.scss +83 -75
  46. data/assets/stylesheets/bootstrap/_functions.scss +7 -7
  47. data/assets/stylesheets/bootstrap/_grid.scss +3 -3
  48. data/assets/stylesheets/bootstrap/_helpers.scss +1 -0
  49. data/assets/stylesheets/bootstrap/_list-group.scss +44 -27
  50. data/assets/stylesheets/bootstrap/_maps.scss +54 -0
  51. data/assets/stylesheets/bootstrap/_modal.scss +71 -43
  52. data/assets/stylesheets/bootstrap/_nav.scss +53 -20
  53. data/assets/stylesheets/bootstrap/_navbar.scss +91 -150
  54. data/assets/stylesheets/bootstrap/_offcanvas.scss +119 -59
  55. data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
  56. data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
  57. data/assets/stylesheets/bootstrap/_popover.scss +90 -52
  58. data/assets/stylesheets/bootstrap/_progress.scss +20 -9
  59. data/assets/stylesheets/bootstrap/_reboot.scss +25 -40
  60. data/assets/stylesheets/bootstrap/_root.scss +40 -21
  61. data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
  62. data/assets/stylesheets/bootstrap/_tables.scss +38 -25
  63. data/assets/stylesheets/bootstrap/_toasts.scss +35 -16
  64. data/assets/stylesheets/bootstrap/_tooltip.scss +61 -56
  65. data/assets/stylesheets/bootstrap/_type.scss +2 -0
  66. data/assets/stylesheets/bootstrap/_utilities.scss +43 -26
  67. data/assets/stylesheets/bootstrap/_variables.scss +118 -124
  68. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +3 -6
  69. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +14 -3
  70. data/assets/stylesheets/bootstrap/forms/_form-check.scss +28 -5
  71. data/assets/stylesheets/bootstrap/forms/_form-control.scss +12 -37
  72. data/assets/stylesheets/bootstrap/forms/_form-select.scss +2 -1
  73. data/assets/stylesheets/bootstrap/forms/_input-group.scss +15 -7
  74. data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +10 -0
  75. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +2 -2
  76. data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
  77. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
  78. data/assets/stylesheets/bootstrap/helpers/_vr.scss +1 -1
  79. data/assets/stylesheets/bootstrap/mixins/_alert.scss +7 -3
  80. data/assets/stylesheets/bootstrap/mixins/_banner.scss +9 -0
  81. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
  82. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
  83. data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
  84. data/assets/stylesheets/bootstrap/mixins/_forms.scss +8 -0
  85. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
  86. data/assets/stylesheets/bootstrap/mixins/_grid.scss +13 -12
  87. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
  88. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
  89. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
  90. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +12 -4
  91. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +1 -1
  92. data/bootstrap.gemspec +1 -1
  93. data/lib/bootstrap/version.rb +2 -2
  94. data/tasks/updater/js.rb +9 -4
  95. metadata +16 -4
@@ -1,236 +1,48 @@
1
1
  /*!
2
- * Bootstrap dropdown.js v5.1.1 (https://getbootstrap.com/)
3
- * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
2
+ * Bootstrap dropdown.js v5.2.0 (https://getbootstrap.com/)
3
+ * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
5
  */
6
6
  (function (global, factory) {
7
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./dom/event-handler.js'), require('./dom/manipulator.js'), require('./dom/selector-engine.js'), require('./base-component.js')) :
8
- typeof define === 'function' && define.amd ? define(['@popperjs/core', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global.Popper, global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
10
- }(this, (function (Popper, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
7
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core'), require('./util/index'), require('./dom/event-handler'), require('./dom/manipulator'), require('./dom/selector-engine'), require('./base-component')) :
8
+ typeof define === 'function' && define.amd ? define(['@popperjs/core', './util/index', './dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
9
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Dropdown = factory(global["@popperjs/core"], global.Index, global.EventHandler, global.Manipulator, global.SelectorEngine, global.BaseComponent));
10
+ })(this, (function (Popper, index, EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
11
11
 
12
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+ const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
13
13
 
14
14
  function _interopNamespace(e) {
15
15
  if (e && e.__esModule) return e;
16
- var n = Object.create(null);
16
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
17
17
  if (e) {
18
- Object.keys(e).forEach(function (k) {
18
+ for (const k in e) {
19
19
  if (k !== 'default') {
20
- var d = Object.getOwnPropertyDescriptor(e, k);
20
+ const d = Object.getOwnPropertyDescriptor(e, k);
21
21
  Object.defineProperty(n, k, d.get ? d : {
22
22
  enumerable: true,
23
- get: function () {
24
- return e[k];
25
- }
23
+ get: () => e[k]
26
24
  });
27
25
  }
28
- });
26
+ }
29
27
  }
30
- n['default'] = e;
28
+ n.default = e;
31
29
  return Object.freeze(n);
32
30
  }
33
31
 
34
- var Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
35
- var EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
36
- var Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
37
- var SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
38
- var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
39
-
40
- /**
41
- * --------------------------------------------------------------------------
42
- * Bootstrap (v5.1.1): util/index.js
43
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
44
- * --------------------------------------------------------------------------
45
- */
46
-
47
- const toType = obj => {
48
- if (obj === null || obj === undefined) {
49
- return `${obj}`;
50
- }
51
-
52
- return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
53
- };
54
-
55
- const getSelector = element => {
56
- let selector = element.getAttribute('data-bs-target');
57
-
58
- if (!selector || selector === '#') {
59
- let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
60
- // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
61
- // `document.querySelector` will rightfully complain it is invalid.
62
- // See https://github.com/twbs/bootstrap/issues/32273
63
-
64
- if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
65
- return null;
66
- } // Just in case some CMS puts out a full URL with the anchor appended
67
-
68
-
69
- if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
70
- hrefAttr = `#${hrefAttr.split('#')[1]}`;
71
- }
72
-
73
- selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
74
- }
75
-
76
- return selector;
77
- };
78
-
79
- const getElementFromSelector = element => {
80
- const selector = getSelector(element);
81
- return selector ? document.querySelector(selector) : null;
82
- };
83
-
84
- const isElement = obj => {
85
- if (!obj || typeof obj !== 'object') {
86
- return false;
87
- }
88
-
89
- if (typeof obj.jquery !== 'undefined') {
90
- obj = obj[0];
91
- }
92
-
93
- return typeof obj.nodeType !== 'undefined';
94
- };
95
-
96
- const getElement = obj => {
97
- if (isElement(obj)) {
98
- // it's a jQuery object or a node element
99
- return obj.jquery ? obj[0] : obj;
100
- }
101
-
102
- if (typeof obj === 'string' && obj.length > 0) {
103
- return document.querySelector(obj);
104
- }
105
-
106
- return null;
107
- };
108
-
109
- const typeCheckConfig = (componentName, config, configTypes) => {
110
- Object.keys(configTypes).forEach(property => {
111
- const expectedTypes = configTypes[property];
112
- const value = config[property];
113
- const valueType = value && isElement(value) ? 'element' : toType(value);
114
-
115
- if (!new RegExp(expectedTypes).test(valueType)) {
116
- throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
117
- }
118
- });
119
- };
120
-
121
- const isVisible = element => {
122
- if (!isElement(element) || element.getClientRects().length === 0) {
123
- return false;
124
- }
125
-
126
- return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
127
- };
128
-
129
- const isDisabled = element => {
130
- if (!element || element.nodeType !== Node.ELEMENT_NODE) {
131
- return true;
132
- }
133
-
134
- if (element.classList.contains('disabled')) {
135
- return true;
136
- }
137
-
138
- if (typeof element.disabled !== 'undefined') {
139
- return element.disabled;
140
- }
141
-
142
- return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
143
- };
144
-
145
- const noop = () => {};
146
-
147
- const getjQuery = () => {
148
- const {
149
- jQuery
150
- } = window;
151
-
152
- if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
153
- return jQuery;
154
- }
155
-
156
- return null;
157
- };
158
-
159
- const DOMContentLoadedCallbacks = [];
160
-
161
- const onDOMContentLoaded = callback => {
162
- if (document.readyState === 'loading') {
163
- // add listener on the first call when the document is in loading state
164
- if (!DOMContentLoadedCallbacks.length) {
165
- document.addEventListener('DOMContentLoaded', () => {
166
- DOMContentLoadedCallbacks.forEach(callback => callback());
167
- });
168
- }
169
-
170
- DOMContentLoadedCallbacks.push(callback);
171
- } else {
172
- callback();
173
- }
174
- };
175
-
176
- const isRTL = () => document.documentElement.dir === 'rtl';
177
-
178
- const defineJQueryPlugin = plugin => {
179
- onDOMContentLoaded(() => {
180
- const $ = getjQuery();
181
- /* istanbul ignore if */
182
-
183
- if ($) {
184
- const name = plugin.NAME;
185
- const JQUERY_NO_CONFLICT = $.fn[name];
186
- $.fn[name] = plugin.jQueryInterface;
187
- $.fn[name].Constructor = plugin;
188
-
189
- $.fn[name].noConflict = () => {
190
- $.fn[name] = JQUERY_NO_CONFLICT;
191
- return plugin.jQueryInterface;
192
- };
193
- }
194
- });
195
- };
196
- /**
197
- * Return the previous/next element of a list.
198
- *
199
- * @param {array} list The list of elements
200
- * @param activeElement The active element
201
- * @param shouldGetNext Choose to get next or previous element
202
- * @param isCycleAllowed
203
- * @return {Element|elem} The proper element
204
- */
205
-
206
-
207
- const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
208
- let index = list.indexOf(activeElement); // if the element does not exist in the list return an element depending on the direction and if cycle is allowed
209
-
210
- if (index === -1) {
211
- return list[!shouldGetNext && isCycleAllowed ? list.length - 1 : 0];
212
- }
213
-
214
- const listLength = list.length;
215
- index += shouldGetNext ? 1 : -1;
216
-
217
- if (isCycleAllowed) {
218
- index = (index + listLength) % listLength;
219
- }
220
-
221
- return list[Math.max(0, Math.min(index, listLength - 1))];
222
- };
32
+ const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
33
+ const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
34
+ const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
35
+ const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
36
+ const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
223
37
 
224
38
  /**
225
39
  * --------------------------------------------------------------------------
226
- * Bootstrap (v5.1.1): dropdown.js
40
+ * Bootstrap (v5.2.0): dropdown.js
227
41
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
228
42
  * --------------------------------------------------------------------------
229
43
  */
230
44
  /**
231
- * ------------------------------------------------------------------------
232
45
  * Constants
233
- * ------------------------------------------------------------------------
234
46
  */
235
47
 
236
48
  const NAME = 'dropdown';
@@ -238,13 +50,11 @@
238
50
  const EVENT_KEY = `.${DATA_KEY}`;
239
51
  const DATA_API_KEY = '.data-api';
240
52
  const ESCAPE_KEY = 'Escape';
241
- const SPACE_KEY = 'Space';
242
53
  const TAB_KEY = 'Tab';
243
54
  const ARROW_UP_KEY = 'ArrowUp';
244
55
  const ARROW_DOWN_KEY = 'ArrowDown';
245
56
  const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
246
57
 
247
- const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY}`);
248
58
  const EVENT_HIDE = `hide${EVENT_KEY}`;
249
59
  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
250
60
  const EVENT_SHOW = `show${EVENT_KEY}`;
@@ -256,45 +66,49 @@
256
66
  const CLASS_NAME_DROPUP = 'dropup';
257
67
  const CLASS_NAME_DROPEND = 'dropend';
258
68
  const CLASS_NAME_DROPSTART = 'dropstart';
259
- const CLASS_NAME_NAVBAR = 'navbar';
260
- const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]';
69
+ const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
70
+ const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
71
+ const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
72
+ const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE}.${CLASS_NAME_SHOW}`;
261
73
  const SELECTOR_MENU = '.dropdown-menu';
74
+ const SELECTOR_NAVBAR = '.navbar';
262
75
  const SELECTOR_NAVBAR_NAV = '.navbar-nav';
263
76
  const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
264
- const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
265
- const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
266
- const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
267
- const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
268
- const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
269
- const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
77
+ const PLACEMENT_TOP = index.isRTL() ? 'top-end' : 'top-start';
78
+ const PLACEMENT_TOPEND = index.isRTL() ? 'top-start' : 'top-end';
79
+ const PLACEMENT_BOTTOM = index.isRTL() ? 'bottom-end' : 'bottom-start';
80
+ const PLACEMENT_BOTTOMEND = index.isRTL() ? 'bottom-start' : 'bottom-end';
81
+ const PLACEMENT_RIGHT = index.isRTL() ? 'left-start' : 'right-start';
82
+ const PLACEMENT_LEFT = index.isRTL() ? 'right-start' : 'left-start';
83
+ const PLACEMENT_TOPCENTER = 'top';
84
+ const PLACEMENT_BOTTOMCENTER = 'bottom';
270
85
  const Default = {
271
- offset: [0, 2],
86
+ autoClose: true,
272
87
  boundary: 'clippingParents',
273
- reference: 'toggle',
274
88
  display: 'dynamic',
89
+ offset: [0, 2],
275
90
  popperConfig: null,
276
- autoClose: true
91
+ reference: 'toggle'
277
92
  };
278
93
  const DefaultType = {
279
- offset: '(array|string|function)',
94
+ autoClose: '(boolean|string)',
280
95
  boundary: '(string|element)',
281
- reference: '(string|element|object)',
282
96
  display: 'string',
97
+ offset: '(array|string|function)',
283
98
  popperConfig: '(null|object|function)',
284
- autoClose: '(boolean|string)'
99
+ reference: '(string|element|object)'
285
100
  };
286
101
  /**
287
- * ------------------------------------------------------------------------
288
- * Class Definition
289
- * ------------------------------------------------------------------------
102
+ * Class definition
290
103
  */
291
104
 
292
- class Dropdown extends BaseComponent__default['default'] {
105
+ class Dropdown extends BaseComponent__default.default {
293
106
  constructor(element, config) {
294
- super(element);
107
+ super(element, config);
295
108
  this._popper = null;
296
- this._config = this._getConfig(config);
297
- this._menu = this._getMenuElement();
109
+ this._parent = this._element.parentNode; // dropdown wrapper
110
+
111
+ this._menu = SelectorEngine__default.default.findOne(SELECTOR_MENU, this._parent);
298
112
  this._inNavbar = this._detectNavbar();
299
113
  } // Getters
300
114
 
@@ -317,33 +131,29 @@
317
131
  }
318
132
 
319
133
  show() {
320
- if (isDisabled(this._element) || this._isShown(this._menu)) {
134
+ if (index.isDisabled(this._element) || this._isShown()) {
321
135
  return;
322
136
  }
323
137
 
324
138
  const relatedTarget = {
325
139
  relatedTarget: this._element
326
140
  };
327
- const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, relatedTarget);
141
+ const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, relatedTarget);
328
142
 
329
143
  if (showEvent.defaultPrevented) {
330
144
  return;
331
145
  }
332
146
 
333
- const parent = Dropdown.getParentFromElement(this._element); // Totally disable Popper for Dropdowns in Navbar
334
-
335
- if (this._inNavbar) {
336
- Manipulator__default['default'].setDataAttribute(this._menu, 'popper', 'none');
337
- } else {
338
- this._createPopper(parent);
339
- } // If this is a touch-enabled device we add extra
147
+ this._createPopper(); // If this is a touch-enabled device we add extra
340
148
  // empty mouseover listeners to the body's immediate children;
341
149
  // only needed because of broken event delegation on iOS
342
150
  // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
343
151
 
344
152
 
345
- if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
346
- [].concat(...document.body.children).forEach(elem => EventHandler__default['default'].on(elem, 'mouseover', noop));
153
+ if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
154
+ for (const element of [].concat(...document.body.children)) {
155
+ EventHandler__default.default.on(element, 'mouseover', index.noop);
156
+ }
347
157
  }
348
158
 
349
159
  this._element.focus();
@@ -354,11 +164,11 @@
354
164
 
355
165
  this._element.classList.add(CLASS_NAME_SHOW);
356
166
 
357
- EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, relatedTarget);
167
+ EventHandler__default.default.trigger(this._element, EVENT_SHOWN, relatedTarget);
358
168
  }
359
169
 
360
170
  hide() {
361
- if (isDisabled(this._element) || !this._isShown(this._menu)) {
171
+ if (index.isDisabled(this._element) || !this._isShown()) {
362
172
  return;
363
173
  }
364
174
 
@@ -387,7 +197,7 @@
387
197
 
388
198
 
389
199
  _completeHide(relatedTarget) {
390
- const hideEvent = EventHandler__default['default'].trigger(this._element, EVENT_HIDE, relatedTarget);
200
+ const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE, relatedTarget);
391
201
 
392
202
  if (hideEvent.defaultPrevented) {
393
203
  return;
@@ -396,7 +206,9 @@
396
206
 
397
207
 
398
208
  if ('ontouchstart' in document.documentElement) {
399
- [].concat(...document.body.children).forEach(elem => EventHandler__default['default'].off(elem, 'mouseover', noop));
209
+ for (const element of [].concat(...document.body.children)) {
210
+ EventHandler__default.default.off(element, 'mouseover', index.noop);
211
+ }
400
212
  }
401
213
 
402
214
  if (this._popper) {
@@ -409,18 +221,14 @@
409
221
 
410
222
  this._element.setAttribute('aria-expanded', 'false');
411
223
 
412
- Manipulator__default['default'].removeDataAttribute(this._menu, 'popper');
413
- EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN, relatedTarget);
224
+ Manipulator__default.default.removeDataAttribute(this._menu, 'popper');
225
+ EventHandler__default.default.trigger(this._element, EVENT_HIDDEN, relatedTarget);
414
226
  }
415
227
 
416
228
  _getConfig(config) {
417
- config = { ...this.constructor.Default,
418
- ...Manipulator__default['default'].getDataAttributes(this._element),
419
- ...config
420
- };
421
- typeCheckConfig(NAME, config, this.constructor.DefaultType);
229
+ config = super._getConfig(config);
422
230
 
423
- if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
231
+ if (typeof config.reference === 'object' && !index.isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
424
232
  // Popper virtual elements require a getBoundingClientRect method
425
233
  throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
426
234
  }
@@ -428,7 +236,7 @@
428
236
  return config;
429
237
  }
430
238
 
431
- _createPopper(parent) {
239
+ _createPopper() {
432
240
  if (typeof Popper__namespace === 'undefined') {
433
241
  throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
434
242
  }
@@ -436,33 +244,24 @@
436
244
  let referenceElement = this._element;
437
245
 
438
246
  if (this._config.reference === 'parent') {
439
- referenceElement = parent;
440
- } else if (isElement(this._config.reference)) {
441
- referenceElement = getElement(this._config.reference);
247
+ referenceElement = this._parent;
248
+ } else if (index.isElement(this._config.reference)) {
249
+ referenceElement = index.getElement(this._config.reference);
442
250
  } else if (typeof this._config.reference === 'object') {
443
251
  referenceElement = this._config.reference;
444
252
  }
445
253
 
446
254
  const popperConfig = this._getPopperConfig();
447
255
 
448
- const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);
449
256
  this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
450
-
451
- if (isDisplayStatic) {
452
- Manipulator__default['default'].setDataAttribute(this._menu, 'popper', 'static');
453
- }
454
257
  }
455
258
 
456
- _isShown(element = this._element) {
457
- return element.classList.contains(CLASS_NAME_SHOW);
458
- }
459
-
460
- _getMenuElement() {
461
- return SelectorEngine__default['default'].next(this._element, SELECTOR_MENU)[0];
259
+ _isShown() {
260
+ return this._menu.classList.contains(CLASS_NAME_SHOW);
462
261
  }
463
262
 
464
263
  _getPlacement() {
465
- const parentDropdown = this._element.parentNode;
264
+ const parentDropdown = this._parent;
466
265
 
467
266
  if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
468
267
  return PLACEMENT_RIGHT;
@@ -470,6 +269,14 @@
470
269
 
471
270
  if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
472
271
  return PLACEMENT_LEFT;
272
+ }
273
+
274
+ if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
275
+ return PLACEMENT_TOPCENTER;
276
+ }
277
+
278
+ if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
279
+ return PLACEMENT_BOTTOMCENTER;
473
280
  } // We need to trim the value because custom properties can also include spaces
474
281
 
475
282
 
@@ -483,7 +290,7 @@
483
290
  }
484
291
 
485
292
  _detectNavbar() {
486
- return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;
293
+ return this._element.closest(SELECTOR_NAVBAR) !== null;
487
294
  }
488
295
 
489
296
  _getOffset() {
@@ -492,7 +299,7 @@
492
299
  } = this._config;
493
300
 
494
301
  if (typeof offset === 'string') {
495
- return offset.split(',').map(val => Number.parseInt(val, 10));
302
+ return offset.split(',').map(value => Number.parseInt(value, 10));
496
303
  }
497
304
 
498
305
  if (typeof offset === 'function') {
@@ -516,9 +323,11 @@
516
323
  offset: this._getOffset()
517
324
  }
518
325
  }]
519
- }; // Disable Popper if we have a static display
326
+ }; // Disable Popper if we have a static display or Dropdown is in Navbar
327
+
328
+ if (this._inNavbar || this._config.display === 'static') {
329
+ Manipulator__default.default.setDataAttribute(this._menu, 'popper', 'static'); // todo:v6 remove
520
330
 
521
- if (this._config.display === 'static') {
522
331
  defaultBsPopperConfig.modifiers = [{
523
332
  name: 'applyStyles',
524
333
  enabled: false
@@ -534,7 +343,7 @@
534
343
  key,
535
344
  target
536
345
  }) {
537
- const items = SelectorEngine__default['default'].find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(isVisible);
346
+ const items = SelectorEngine__default.default.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => index.isVisible(element));
538
347
 
539
348
  if (!items.length) {
540
349
  return;
@@ -542,7 +351,7 @@
542
351
  // allow cycling to get the last item in case key equals ARROW_UP_KEY
543
352
 
544
353
 
545
- getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
354
+ index.getNextActiveElement(items, target, key === ARROW_DOWN_KEY, !items.includes(target)).focus();
546
355
  } // Static
547
356
 
548
357
 
@@ -563,20 +372,28 @@
563
372
  }
564
373
 
565
374
  static clearMenus(event) {
566
- if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY)) {
375
+ if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) {
567
376
  return;
568
377
  }
569
378
 
570
- const toggles = SelectorEngine__default['default'].find(SELECTOR_DATA_TOGGLE);
379
+ const openToggles = SelectorEngine__default.default.find(SELECTOR_DATA_TOGGLE_SHOWN);
571
380
 
572
- for (let i = 0, len = toggles.length; i < len; i++) {
573
- const context = Dropdown.getInstance(toggles[i]);
381
+ for (const toggle of openToggles) {
382
+ const context = Dropdown.getInstance(toggle);
574
383
 
575
384
  if (!context || context._config.autoClose === false) {
576
385
  continue;
577
386
  }
578
387
 
579
- if (!context._isShown()) {
388
+ const composedPath = event.composedPath();
389
+ const isMenuTarget = composedPath.includes(context._menu);
390
+
391
+ if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
392
+ continue;
393
+ } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
394
+
395
+
396
+ if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY || /input|select|option|textarea|form/i.test(event.target.tagName))) {
580
397
  continue;
581
398
  }
582
399
 
@@ -584,105 +401,70 @@
584
401
  relatedTarget: context._element
585
402
  };
586
403
 
587
- if (event) {
588
- const composedPath = event.composedPath();
589
- const isMenuTarget = composedPath.includes(context._menu);
590
-
591
- if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
592
- continue;
593
- } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
594
-
595
-
596
- if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY || /input|select|option|textarea|form/i.test(event.target.tagName))) {
597
- continue;
598
- }
599
-
600
- if (event.type === 'click') {
601
- relatedTarget.clickEvent = event;
602
- }
404
+ if (event.type === 'click') {
405
+ relatedTarget.clickEvent = event;
603
406
  }
604
407
 
605
408
  context._completeHide(relatedTarget);
606
409
  }
607
410
  }
608
411
 
609
- static getParentFromElement(element) {
610
- return getElementFromSelector(element) || element.parentNode;
611
- }
612
-
613
412
  static dataApiKeydownHandler(event) {
614
- // If not input/textarea:
615
- // - And not a key in REGEXP_KEYDOWN => not a dropdown command
616
- // If input/textarea:
617
- // - If space key => not a dropdown command
618
- // - If key is other than escape
619
- // - If key is not up or down => not a dropdown command
620
- // - If trigger inside the menu => not a dropdown command
621
- if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {
622
- return;
623
- }
624
-
625
- const isActive = this.classList.contains(CLASS_NAME_SHOW);
413
+ // If not an UP | DOWN | ESCAPE key => not a dropdown command
414
+ // If input/textarea && if key is other than ESCAPE => not a dropdown command
415
+ const isInput = /input|textarea/i.test(event.target.tagName);
416
+ const isEscapeEvent = event.key === ESCAPE_KEY;
417
+ const isUpOrDownEvent = [ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key);
626
418
 
627
- if (!isActive && event.key === ESCAPE_KEY) {
419
+ if (!isUpOrDownEvent && !isEscapeEvent) {
628
420
  return;
629
421
  }
630
422
 
631
- event.preventDefault();
632
- event.stopPropagation();
633
-
634
- if (isDisabled(this)) {
423
+ if (isInput && !isEscapeEvent) {
635
424
  return;
636
425
  }
637
426
 
638
- const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE) ? this : SelectorEngine__default['default'].prev(this, SELECTOR_DATA_TOGGLE)[0];
427
+ event.preventDefault();
428
+ const getToggleButton = SelectorEngine__default.default.findOne(SELECTOR_DATA_TOGGLE, event.delegateTarget.parentNode);
639
429
  const instance = Dropdown.getOrCreateInstance(getToggleButton);
640
430
 
641
- if (event.key === ESCAPE_KEY) {
642
- instance.hide();
643
- return;
644
- }
645
-
646
- if (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY) {
647
- if (!isActive) {
648
- instance.show();
649
- }
431
+ if (isUpOrDownEvent) {
432
+ event.stopPropagation();
433
+ instance.show();
650
434
 
651
435
  instance._selectMenuItem(event);
652
436
 
653
437
  return;
654
438
  }
655
439
 
656
- if (!isActive || event.key === SPACE_KEY) {
657
- Dropdown.clearMenus();
440
+ if (instance._isShown()) {
441
+ // else is escape and we check if it is shown
442
+ event.stopPropagation();
443
+ instance.hide();
444
+ getToggleButton.focus();
658
445
  }
659
446
  }
660
447
 
661
448
  }
662
449
  /**
663
- * ------------------------------------------------------------------------
664
- * Data Api implementation
665
- * ------------------------------------------------------------------------
450
+ * Data API implementation
666
451
  */
667
452
 
668
453
 
669
- EventHandler__default['default'].on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler);
670
- EventHandler__default['default'].on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
671
- EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
672
- EventHandler__default['default'].on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
673
- EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
454
+ EventHandler__default.default.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown.dataApiKeydownHandler);
455
+ EventHandler__default.default.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
456
+ EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, Dropdown.clearMenus);
457
+ EventHandler__default.default.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
458
+ EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
674
459
  event.preventDefault();
675
460
  Dropdown.getOrCreateInstance(this).toggle();
676
461
  });
677
462
  /**
678
- * ------------------------------------------------------------------------
679
463
  * jQuery
680
- * ------------------------------------------------------------------------
681
- * add .Dropdown to jQuery only if jQuery is present
682
464
  */
683
465
 
684
- defineJQueryPlugin(Dropdown);
466
+ index.defineJQueryPlugin(Dropdown);
685
467
 
686
468
  return Dropdown;
687
469
 
688
- })));
470
+ }));