bootstrap 5.1.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }));