bootstrap 5.0.1 → 5.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/assets/javascripts/bootstrap/alert.js +89 -58
- data/assets/javascripts/bootstrap/base-component.js +53 -39
- data/assets/javascripts/bootstrap/button.js +31 -25
- data/assets/javascripts/bootstrap/carousel.js +126 -89
- data/assets/javascripts/bootstrap/collapse.js +125 -133
- data/assets/javascripts/bootstrap/dom/data.js +5 -5
- data/assets/javascripts/bootstrap/dom/event-handler.js +11 -5
- data/assets/javascripts/bootstrap/dom/manipulator.js +6 -6
- data/assets/javascripts/bootstrap/dom/selector-engine.js +49 -7
- data/assets/javascripts/bootstrap/dropdown.js +147 -140
- data/assets/javascripts/bootstrap/modal.js +397 -180
- data/assets/javascripts/bootstrap/offcanvas.js +333 -138
- data/assets/javascripts/bootstrap/popover.js +36 -54
- data/assets/javascripts/bootstrap/scrollspy.js +58 -68
- data/assets/javascripts/bootstrap/tab.js +53 -26
- data/assets/javascripts/bootstrap/toast.js +138 -41
- data/assets/javascripts/bootstrap/tooltip.js +137 -120
- data/assets/javascripts/bootstrap-sprockets.js +8 -8
- data/assets/javascripts/bootstrap.js +937 -886
- data/assets/javascripts/bootstrap.min.js +2 -2
- data/assets/stylesheets/_bootstrap-grid.scss +3 -1
- data/assets/stylesheets/_bootstrap-reboot.scss +2 -4
- data/assets/stylesheets/_bootstrap.scss +2 -1
- data/assets/stylesheets/bootstrap/_buttons.scss +1 -0
- data/assets/stylesheets/bootstrap/_card.scss +7 -6
- data/assets/stylesheets/bootstrap/_carousel.scss +2 -2
- data/assets/stylesheets/bootstrap/_dropdown.scss +4 -4
- data/assets/stylesheets/bootstrap/_functions.scss +100 -3
- data/assets/stylesheets/bootstrap/_grid.scss +11 -0
- data/assets/stylesheets/bootstrap/_helpers.scss +2 -0
- data/assets/stylesheets/bootstrap/_images.scss +1 -1
- data/assets/stylesheets/bootstrap/_mixins.scss +1 -0
- data/assets/stylesheets/bootstrap/_modal.scss +5 -15
- data/assets/stylesheets/bootstrap/_navbar.scss +30 -1
- data/assets/stylesheets/bootstrap/_offcanvas.scss +8 -2
- data/assets/stylesheets/bootstrap/_placeholders.scss +51 -0
- data/assets/stylesheets/bootstrap/_popover.scss +10 -10
- data/assets/stylesheets/bootstrap/_reboot.scss +12 -8
- data/assets/stylesheets/bootstrap/_root.scss +40 -2
- data/assets/stylesheets/bootstrap/_tables.scss +9 -5
- data/assets/stylesheets/bootstrap/_toasts.scss +3 -3
- data/assets/stylesheets/bootstrap/_tooltip.scss +4 -4
- data/assets/stylesheets/bootstrap/_transitions.scss +6 -0
- data/assets/stylesheets/bootstrap/_utilities.scss +44 -8
- data/assets/stylesheets/bootstrap/_variables.scss +206 -29
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +1 -1
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +3 -1
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +1 -1
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +1 -1
- data/assets/stylesheets/bootstrap/forms/_form-range.scss +1 -1
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +5 -0
- data/assets/stylesheets/bootstrap/helpers/_stacks.scss +15 -0
- data/assets/stylesheets/bootstrap/helpers/_vr.scss +8 -0
- data/assets/stylesheets/bootstrap/mixins/_backdrop.scss +14 -0
- data/assets/stylesheets/bootstrap/mixins/_buttons.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +35 -9
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +27 -6
- data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +1 -1
- data/assets/stylesheets/bootstrap/vendor/_rfs.scss +55 -13
- data/bootstrap.gemspec +3 -3
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +6 -2
- metadata +12 -8
@@ -1,21 +1,27 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap modal.js v5.
|
2
|
+
* Bootstrap modal.js v5.1.2 (https://getbootstrap.com/)
|
3
3
|
* Copyright 2011-2021 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('./dom/
|
8
|
-
typeof define === 'function' && define.amd ? define(['./dom/
|
9
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.
|
10
|
-
}(this, (function (
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(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(['./dom/event-handler', './dom/manipulator', './dom/selector-engine', './base-component'], factory) :
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.EventHandler, global.Manipulator, global.SelectorEngine, global.Base));
|
10
|
+
})(this, (function (EventHandler, Manipulator, SelectorEngine, BaseComponent) { 'use strict';
|
11
11
|
|
12
|
-
|
12
|
+
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
15
|
+
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
16
|
+
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
17
|
+
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
18
18
|
|
19
|
+
/**
|
20
|
+
* --------------------------------------------------------------------------
|
21
|
+
* Bootstrap (v5.1.2): util/index.js
|
22
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
23
|
+
* --------------------------------------------------------------------------
|
24
|
+
*/
|
19
25
|
const MILLISECONDS_MULTIPLIER = 1000;
|
20
26
|
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
21
27
|
|
@@ -95,22 +101,17 @@
|
|
95
101
|
return typeof obj.nodeType !== 'undefined';
|
96
102
|
};
|
97
103
|
|
98
|
-
const
|
99
|
-
|
100
|
-
|
101
|
-
|
104
|
+
const getElement = obj => {
|
105
|
+
if (isElement(obj)) {
|
106
|
+
// it's a jQuery object or a node element
|
107
|
+
return obj.jquery ? obj[0] : obj;
|
108
|
+
}
|
102
109
|
|
103
|
-
|
104
|
-
|
105
|
-
element.removeEventListener(TRANSITION_END, listener);
|
110
|
+
if (typeof obj === 'string' && obj.length > 0) {
|
111
|
+
return document.querySelector(obj);
|
106
112
|
}
|
107
113
|
|
108
|
-
|
109
|
-
setTimeout(() => {
|
110
|
-
if (!called) {
|
111
|
-
triggerTransitionEnd(element);
|
112
|
-
}
|
113
|
-
}, emulatedDuration);
|
114
|
+
return null;
|
114
115
|
};
|
115
116
|
|
116
117
|
const typeCheckConfig = (componentName, config, configTypes) => {
|
@@ -126,20 +127,42 @@
|
|
126
127
|
};
|
127
128
|
|
128
129
|
const isVisible = element => {
|
129
|
-
if (!element) {
|
130
|
+
if (!isElement(element) || element.getClientRects().length === 0) {
|
130
131
|
return false;
|
131
132
|
}
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
134
|
+
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
135
|
+
};
|
136
|
+
|
137
|
+
const isDisabled = element => {
|
138
|
+
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
139
|
+
return true;
|
140
|
+
}
|
141
|
+
|
142
|
+
if (element.classList.contains('disabled')) {
|
143
|
+
return true;
|
137
144
|
}
|
138
145
|
|
139
|
-
|
146
|
+
if (typeof element.disabled !== 'undefined') {
|
147
|
+
return element.disabled;
|
148
|
+
}
|
149
|
+
|
150
|
+
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
140
151
|
};
|
152
|
+
/**
|
153
|
+
* Trick to restart an element's animation
|
154
|
+
*
|
155
|
+
* @param {HTMLElement} element
|
156
|
+
* @return void
|
157
|
+
*
|
158
|
+
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
159
|
+
*/
|
160
|
+
|
141
161
|
|
142
|
-
const reflow = element =>
|
162
|
+
const reflow = element => {
|
163
|
+
// eslint-disable-next-line no-unused-expressions
|
164
|
+
element.offsetHeight;
|
165
|
+
};
|
143
166
|
|
144
167
|
const getjQuery = () => {
|
145
168
|
const {
|
@@ -153,9 +176,18 @@
|
|
153
176
|
return null;
|
154
177
|
};
|
155
178
|
|
179
|
+
const DOMContentLoadedCallbacks = [];
|
180
|
+
|
156
181
|
const onDOMContentLoaded = callback => {
|
157
182
|
if (document.readyState === 'loading') {
|
158
|
-
document
|
183
|
+
// add listener on the first call when the document is in loading state
|
184
|
+
if (!DOMContentLoadedCallbacks.length) {
|
185
|
+
document.addEventListener('DOMContentLoaded', () => {
|
186
|
+
DOMContentLoadedCallbacks.forEach(callback => callback());
|
187
|
+
});
|
188
|
+
}
|
189
|
+
|
190
|
+
DOMContentLoadedCallbacks.push(callback);
|
159
191
|
} else {
|
160
192
|
callback();
|
161
193
|
}
|
@@ -188,105 +220,166 @@
|
|
188
220
|
}
|
189
221
|
};
|
190
222
|
|
223
|
+
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
224
|
+
if (!waitForTransition) {
|
225
|
+
execute(callback);
|
226
|
+
return;
|
227
|
+
}
|
228
|
+
|
229
|
+
const durationPadding = 5;
|
230
|
+
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
231
|
+
let called = false;
|
232
|
+
|
233
|
+
const handler = ({
|
234
|
+
target
|
235
|
+
}) => {
|
236
|
+
if (target !== transitionElement) {
|
237
|
+
return;
|
238
|
+
}
|
239
|
+
|
240
|
+
called = true;
|
241
|
+
transitionElement.removeEventListener(TRANSITION_END, handler);
|
242
|
+
execute(callback);
|
243
|
+
};
|
244
|
+
|
245
|
+
transitionElement.addEventListener(TRANSITION_END, handler);
|
246
|
+
setTimeout(() => {
|
247
|
+
if (!called) {
|
248
|
+
triggerTransitionEnd(transitionElement);
|
249
|
+
}
|
250
|
+
}, emulatedDuration);
|
251
|
+
};
|
252
|
+
|
191
253
|
/**
|
192
254
|
* --------------------------------------------------------------------------
|
193
|
-
* Bootstrap (v5.
|
255
|
+
* Bootstrap (v5.1.2): util/scrollBar.js
|
194
256
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
195
257
|
* --------------------------------------------------------------------------
|
196
258
|
*/
|
197
259
|
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
198
260
|
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
199
261
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
};
|
262
|
+
class ScrollBarHelper {
|
263
|
+
constructor() {
|
264
|
+
this._element = document.body;
|
265
|
+
}
|
205
266
|
|
206
|
-
|
207
|
-
|
267
|
+
getWidth() {
|
268
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
269
|
+
const documentWidth = document.documentElement.clientWidth;
|
270
|
+
return Math.abs(window.innerWidth - documentWidth);
|
271
|
+
}
|
208
272
|
|
273
|
+
hide() {
|
274
|
+
const width = this.getWidth();
|
209
275
|
|
210
|
-
|
276
|
+
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
|
211
277
|
|
212
278
|
|
213
|
-
|
279
|
+
this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
214
280
|
|
215
|
-
_setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
216
|
-
};
|
217
281
|
|
218
|
-
|
219
|
-
const actualValue = document.body.style.overflow;
|
282
|
+
this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
|
220
283
|
|
221
|
-
|
222
|
-
Manipulator__default['default'].setDataAttribute(document.body, 'overflow', actualValue);
|
284
|
+
this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
223
285
|
}
|
224
286
|
|
225
|
-
|
226
|
-
|
287
|
+
_disableOverFlow() {
|
288
|
+
this._saveInitialAttribute(this._element, 'overflow');
|
227
289
|
|
228
|
-
|
229
|
-
|
230
|
-
SelectorEngine__default['default'].find(selector).forEach(element => {
|
231
|
-
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
232
|
-
return;
|
233
|
-
}
|
290
|
+
this._element.style.overflow = 'hidden';
|
291
|
+
}
|
234
292
|
|
235
|
-
|
236
|
-
const
|
237
|
-
Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
|
238
|
-
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
|
239
|
-
});
|
240
|
-
};
|
293
|
+
_setElementAttributes(selector, styleProp, callback) {
|
294
|
+
const scrollbarWidth = this.getWidth();
|
241
295
|
|
242
|
-
|
243
|
-
|
296
|
+
const manipulationCallBack = element => {
|
297
|
+
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
298
|
+
return;
|
299
|
+
}
|
300
|
+
|
301
|
+
this._saveInitialAttribute(element, styleProp);
|
244
302
|
|
245
|
-
|
303
|
+
const calculatedValue = window.getComputedStyle(element)[styleProp];
|
304
|
+
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
|
305
|
+
};
|
246
306
|
|
247
|
-
|
307
|
+
this._applyManipulationCallback(selector, manipulationCallBack);
|
308
|
+
}
|
248
309
|
|
249
|
-
|
250
|
-
|
310
|
+
reset() {
|
311
|
+
this._resetElementAttributes(this._element, 'overflow');
|
251
312
|
|
252
|
-
|
253
|
-
|
254
|
-
|
313
|
+
this._resetElementAttributes(this._element, 'paddingRight');
|
314
|
+
|
315
|
+
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
|
316
|
+
|
317
|
+
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
|
318
|
+
}
|
319
|
+
|
320
|
+
_saveInitialAttribute(element, styleProp) {
|
321
|
+
const actualValue = element.style[styleProp];
|
322
|
+
|
323
|
+
if (actualValue) {
|
324
|
+
Manipulator__default.default.setDataAttribute(element, styleProp, actualValue);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
_resetElementAttributes(selector, styleProp) {
|
329
|
+
const manipulationCallBack = element => {
|
330
|
+
const value = Manipulator__default.default.getDataAttribute(element, styleProp);
|
331
|
+
|
332
|
+
if (typeof value === 'undefined') {
|
333
|
+
element.style.removeProperty(styleProp);
|
334
|
+
} else {
|
335
|
+
Manipulator__default.default.removeDataAttribute(element, styleProp);
|
336
|
+
element.style[styleProp] = value;
|
337
|
+
}
|
338
|
+
};
|
255
339
|
|
256
|
-
|
257
|
-
|
340
|
+
this._applyManipulationCallback(selector, manipulationCallBack);
|
341
|
+
}
|
342
|
+
|
343
|
+
_applyManipulationCallback(selector, callBack) {
|
344
|
+
if (isElement(selector)) {
|
345
|
+
callBack(selector);
|
258
346
|
} else {
|
259
|
-
|
260
|
-
element.style[styleProp] = value;
|
347
|
+
SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
|
261
348
|
}
|
262
|
-
}
|
263
|
-
|
349
|
+
}
|
350
|
+
|
351
|
+
isOverflowing() {
|
352
|
+
return this.getWidth() > 0;
|
353
|
+
}
|
354
|
+
|
355
|
+
}
|
264
356
|
|
265
357
|
/**
|
266
358
|
* --------------------------------------------------------------------------
|
267
|
-
* Bootstrap (v5.
|
268
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/
|
359
|
+
* Bootstrap (v5.1.2): util/backdrop.js
|
360
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
269
361
|
* --------------------------------------------------------------------------
|
270
362
|
*/
|
271
|
-
const Default$
|
363
|
+
const Default$2 = {
|
364
|
+
className: 'modal-backdrop',
|
272
365
|
isVisible: true,
|
273
366
|
// if false, we use the backdrop helper without adding any element to the dom
|
274
367
|
isAnimated: false,
|
275
|
-
rootElement:
|
368
|
+
rootElement: 'body',
|
276
369
|
// give the choice to place backdrop under different elements
|
277
370
|
clickCallback: null
|
278
371
|
};
|
279
|
-
const DefaultType$
|
372
|
+
const DefaultType$2 = {
|
373
|
+
className: 'string',
|
280
374
|
isVisible: 'boolean',
|
281
375
|
isAnimated: 'boolean',
|
282
|
-
rootElement: 'element',
|
376
|
+
rootElement: '(element|string)',
|
283
377
|
clickCallback: '(function|null)'
|
284
378
|
};
|
285
|
-
const NAME$
|
286
|
-
const CLASS_NAME_BACKDROP = 'modal-backdrop';
|
379
|
+
const NAME$2 = 'backdrop';
|
287
380
|
const CLASS_NAME_FADE$1 = 'fade';
|
288
381
|
const CLASS_NAME_SHOW$1 = 'show';
|
289
|
-
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$
|
382
|
+
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
|
290
383
|
|
291
384
|
class Backdrop {
|
292
385
|
constructor(config) {
|
@@ -332,7 +425,7 @@
|
|
332
425
|
_getElement() {
|
333
426
|
if (!this._element) {
|
334
427
|
const backdrop = document.createElement('div');
|
335
|
-
backdrop.className =
|
428
|
+
backdrop.className = this._config.className;
|
336
429
|
|
337
430
|
if (this._config.isAnimated) {
|
338
431
|
backdrop.classList.add(CLASS_NAME_FADE$1);
|
@@ -345,11 +438,12 @@
|
|
345
438
|
}
|
346
439
|
|
347
440
|
_getConfig(config) {
|
348
|
-
config = { ...Default$
|
441
|
+
config = { ...Default$2,
|
349
442
|
...(typeof config === 'object' ? config : {})
|
350
|
-
};
|
351
|
-
|
352
|
-
|
443
|
+
}; // use getElement() with the default "body" to get a fresh Element on each instantiation
|
444
|
+
|
445
|
+
config.rootElement = getElement(config.rootElement);
|
446
|
+
typeCheckConfig(NAME$2, config, DefaultType$2);
|
353
447
|
return config;
|
354
448
|
}
|
355
449
|
|
@@ -358,9 +452,9 @@
|
|
358
452
|
return;
|
359
453
|
}
|
360
454
|
|
361
|
-
this._config.rootElement.
|
455
|
+
this._config.rootElement.append(this._getElement());
|
362
456
|
|
363
|
-
EventHandler__default
|
457
|
+
EventHandler__default.default.on(this._getElement(), EVENT_MOUSEDOWN, () => {
|
364
458
|
execute(this._config.clickCallback);
|
365
459
|
});
|
366
460
|
this._isAppended = true;
|
@@ -371,29 +465,151 @@
|
|
371
465
|
return;
|
372
466
|
}
|
373
467
|
|
374
|
-
EventHandler__default
|
468
|
+
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
|
375
469
|
|
376
|
-
this.
|
470
|
+
this._element.remove();
|
377
471
|
|
378
472
|
this._isAppended = false;
|
379
473
|
}
|
380
474
|
|
381
475
|
_emulateAnimation(callback) {
|
382
|
-
|
383
|
-
|
476
|
+
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
477
|
+
}
|
478
|
+
|
479
|
+
}
|
480
|
+
|
481
|
+
/**
|
482
|
+
* --------------------------------------------------------------------------
|
483
|
+
* Bootstrap (v5.1.2): util/focustrap.js
|
484
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
485
|
+
* --------------------------------------------------------------------------
|
486
|
+
*/
|
487
|
+
const Default$1 = {
|
488
|
+
trapElement: null,
|
489
|
+
// The element to trap focus inside of
|
490
|
+
autofocus: true
|
491
|
+
};
|
492
|
+
const DefaultType$1 = {
|
493
|
+
trapElement: 'element',
|
494
|
+
autofocus: 'boolean'
|
495
|
+
};
|
496
|
+
const NAME$1 = 'focustrap';
|
497
|
+
const DATA_KEY$1 = 'bs.focustrap';
|
498
|
+
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
499
|
+
const EVENT_FOCUSIN = `focusin${EVENT_KEY$1}`;
|
500
|
+
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$1}`;
|
501
|
+
const TAB_KEY = 'Tab';
|
502
|
+
const TAB_NAV_FORWARD = 'forward';
|
503
|
+
const TAB_NAV_BACKWARD = 'backward';
|
504
|
+
|
505
|
+
class FocusTrap {
|
506
|
+
constructor(config) {
|
507
|
+
this._config = this._getConfig(config);
|
508
|
+
this._isActive = false;
|
509
|
+
this._lastTabNavDirection = null;
|
510
|
+
}
|
511
|
+
|
512
|
+
activate() {
|
513
|
+
const {
|
514
|
+
trapElement,
|
515
|
+
autofocus
|
516
|
+
} = this._config;
|
517
|
+
|
518
|
+
if (this._isActive) {
|
384
519
|
return;
|
385
520
|
}
|
386
521
|
|
387
|
-
|
388
|
-
|
389
|
-
|
522
|
+
if (autofocus) {
|
523
|
+
trapElement.focus();
|
524
|
+
}
|
525
|
+
|
526
|
+
EventHandler__default.default.off(document, EVENT_KEY$1); // guard against infinite focus loop
|
527
|
+
|
528
|
+
EventHandler__default.default.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
|
529
|
+
EventHandler__default.default.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
530
|
+
this._isActive = true;
|
531
|
+
}
|
532
|
+
|
533
|
+
deactivate() {
|
534
|
+
if (!this._isActive) {
|
535
|
+
return;
|
536
|
+
}
|
537
|
+
|
538
|
+
this._isActive = false;
|
539
|
+
EventHandler__default.default.off(document, EVENT_KEY$1);
|
540
|
+
} // Private
|
541
|
+
|
542
|
+
|
543
|
+
_handleFocusin(event) {
|
544
|
+
const {
|
545
|
+
target
|
546
|
+
} = event;
|
547
|
+
const {
|
548
|
+
trapElement
|
549
|
+
} = this._config;
|
550
|
+
|
551
|
+
if (target === document || target === trapElement || trapElement.contains(target)) {
|
552
|
+
return;
|
553
|
+
}
|
554
|
+
|
555
|
+
const elements = SelectorEngine__default.default.focusableChildren(trapElement);
|
556
|
+
|
557
|
+
if (elements.length === 0) {
|
558
|
+
trapElement.focus();
|
559
|
+
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
560
|
+
elements[elements.length - 1].focus();
|
561
|
+
} else {
|
562
|
+
elements[0].focus();
|
563
|
+
}
|
564
|
+
}
|
565
|
+
|
566
|
+
_handleKeydown(event) {
|
567
|
+
if (event.key !== TAB_KEY) {
|
568
|
+
return;
|
569
|
+
}
|
570
|
+
|
571
|
+
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
572
|
+
}
|
573
|
+
|
574
|
+
_getConfig(config) {
|
575
|
+
config = { ...Default$1,
|
576
|
+
...(typeof config === 'object' ? config : {})
|
577
|
+
};
|
578
|
+
typeCheckConfig(NAME$1, config, DefaultType$1);
|
579
|
+
return config;
|
390
580
|
}
|
391
581
|
|
392
582
|
}
|
393
583
|
|
394
584
|
/**
|
395
585
|
* --------------------------------------------------------------------------
|
396
|
-
* Bootstrap (v5.
|
586
|
+
* Bootstrap (v5.1.2): util/component-functions.js
|
587
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
588
|
+
* --------------------------------------------------------------------------
|
589
|
+
*/
|
590
|
+
|
591
|
+
const enableDismissTrigger = (component, method = 'hide') => {
|
592
|
+
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
593
|
+
const name = component.NAME;
|
594
|
+
EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
595
|
+
if (['A', 'AREA'].includes(this.tagName)) {
|
596
|
+
event.preventDefault();
|
597
|
+
}
|
598
|
+
|
599
|
+
if (isDisabled(this)) {
|
600
|
+
return;
|
601
|
+
}
|
602
|
+
|
603
|
+
const target = getElementFromSelector(this) || this.closest(`.${name}`);
|
604
|
+
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
605
|
+
|
606
|
+
instance[method]();
|
607
|
+
});
|
608
|
+
};
|
609
|
+
|
610
|
+
/**
|
611
|
+
* --------------------------------------------------------------------------
|
612
|
+
* Bootstrap (v5.1.2): modal.js
|
397
613
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
398
614
|
* --------------------------------------------------------------------------
|
399
615
|
*/
|
@@ -423,7 +639,6 @@
|
|
423
639
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
424
640
|
const EVENT_SHOW = `show${EVENT_KEY}`;
|
425
641
|
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
426
|
-
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
|
427
642
|
const EVENT_RESIZE = `resize${EVENT_KEY}`;
|
428
643
|
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
|
429
644
|
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
@@ -434,25 +649,27 @@
|
|
434
649
|
const CLASS_NAME_FADE = 'fade';
|
435
650
|
const CLASS_NAME_SHOW = 'show';
|
436
651
|
const CLASS_NAME_STATIC = 'modal-static';
|
652
|
+
const OPEN_SELECTOR = '.modal.show';
|
437
653
|
const SELECTOR_DIALOG = '.modal-dialog';
|
438
654
|
const SELECTOR_MODAL_BODY = '.modal-body';
|
439
655
|
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]';
|
440
|
-
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="modal"]';
|
441
656
|
/**
|
442
657
|
* ------------------------------------------------------------------------
|
443
658
|
* Class Definition
|
444
659
|
* ------------------------------------------------------------------------
|
445
660
|
*/
|
446
661
|
|
447
|
-
class Modal extends BaseComponent__default
|
662
|
+
class Modal extends BaseComponent__default.default {
|
448
663
|
constructor(element, config) {
|
449
664
|
super(element);
|
450
665
|
this._config = this._getConfig(config);
|
451
|
-
this._dialog = SelectorEngine__default
|
666
|
+
this._dialog = SelectorEngine__default.default.findOne(SELECTOR_DIALOG, this._element);
|
452
667
|
this._backdrop = this._initializeBackDrop();
|
668
|
+
this._focustrap = this._initializeFocusTrap();
|
453
669
|
this._isShown = false;
|
454
670
|
this._ignoreBackdropClick = false;
|
455
671
|
this._isTransitioning = false;
|
672
|
+
this._scrollBar = new ScrollBarHelper();
|
456
673
|
} // Getters
|
457
674
|
|
458
675
|
|
@@ -474,20 +691,22 @@
|
|
474
691
|
return;
|
475
692
|
}
|
476
693
|
|
477
|
-
|
478
|
-
this._isTransitioning = true;
|
479
|
-
}
|
480
|
-
|
481
|
-
const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, {
|
694
|
+
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
|
482
695
|
relatedTarget
|
483
696
|
});
|
484
697
|
|
485
|
-
if (
|
698
|
+
if (showEvent.defaultPrevented) {
|
486
699
|
return;
|
487
700
|
}
|
488
701
|
|
489
702
|
this._isShown = true;
|
490
|
-
|
703
|
+
|
704
|
+
if (this._isAnimated()) {
|
705
|
+
this._isTransitioning = true;
|
706
|
+
}
|
707
|
+
|
708
|
+
this._scrollBar.hide();
|
709
|
+
|
491
710
|
document.body.classList.add(CLASS_NAME_OPEN);
|
492
711
|
|
493
712
|
this._adjustDialog();
|
@@ -496,9 +715,8 @@
|
|
496
715
|
|
497
716
|
this._setResizeEvent();
|
498
717
|
|
499
|
-
EventHandler__default
|
500
|
-
|
501
|
-
EventHandler__default['default'].one(this._element, EVENT_MOUSEUP_DISMISS, event => {
|
718
|
+
EventHandler__default.default.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
|
719
|
+
EventHandler__default.default.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
|
502
720
|
if (event.target === this._element) {
|
503
721
|
this._ignoreBackdropClick = true;
|
504
722
|
}
|
@@ -508,16 +726,12 @@
|
|
508
726
|
this._showBackdrop(() => this._showElement(relatedTarget));
|
509
727
|
}
|
510
728
|
|
511
|
-
hide(
|
512
|
-
if (event) {
|
513
|
-
event.preventDefault();
|
514
|
-
}
|
515
|
-
|
729
|
+
hide() {
|
516
730
|
if (!this._isShown || this._isTransitioning) {
|
517
731
|
return;
|
518
732
|
}
|
519
733
|
|
520
|
-
const hideEvent = EventHandler__default
|
734
|
+
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
|
521
735
|
|
522
736
|
if (hideEvent.defaultPrevented) {
|
523
737
|
return;
|
@@ -535,29 +749,24 @@
|
|
535
749
|
|
536
750
|
this._setResizeEvent();
|
537
751
|
|
538
|
-
|
752
|
+
this._focustrap.deactivate();
|
539
753
|
|
540
754
|
this._element.classList.remove(CLASS_NAME_SHOW);
|
541
755
|
|
542
|
-
EventHandler__default
|
543
|
-
EventHandler__default
|
756
|
+
EventHandler__default.default.off(this._element, EVENT_CLICK_DISMISS);
|
757
|
+
EventHandler__default.default.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);
|
544
758
|
|
545
759
|
this._queueCallback(() => this._hideModal(), this._element, isAnimated);
|
546
760
|
}
|
547
761
|
|
548
762
|
dispose() {
|
549
|
-
[window, this._dialog].forEach(htmlElement => EventHandler__default
|
763
|
+
[window, this._dialog].forEach(htmlElement => EventHandler__default.default.off(htmlElement, EVENT_KEY));
|
550
764
|
|
551
765
|
this._backdrop.dispose();
|
552
766
|
|
553
|
-
|
554
|
-
/**
|
555
|
-
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
|
556
|
-
* Do not move `document` in `htmlElements` array
|
557
|
-
* It will remove `EVENT_CLICK_DATA_API` event that should remain
|
558
|
-
*/
|
767
|
+
this._focustrap.deactivate();
|
559
768
|
|
560
|
-
|
769
|
+
super.dispose();
|
561
770
|
}
|
562
771
|
|
563
772
|
handleUpdate() {
|
@@ -573,10 +782,16 @@
|
|
573
782
|
});
|
574
783
|
}
|
575
784
|
|
785
|
+
_initializeFocusTrap() {
|
786
|
+
return new FocusTrap({
|
787
|
+
trapElement: this._element
|
788
|
+
});
|
789
|
+
}
|
790
|
+
|
576
791
|
_getConfig(config) {
|
577
792
|
config = { ...Default,
|
578
|
-
...Manipulator__default
|
579
|
-
...config
|
793
|
+
...Manipulator__default.default.getDataAttributes(this._element),
|
794
|
+
...(typeof config === 'object' ? config : {})
|
580
795
|
};
|
581
796
|
typeCheckConfig(NAME, config, DefaultType);
|
582
797
|
return config;
|
@@ -585,11 +800,11 @@
|
|
585
800
|
_showElement(relatedTarget) {
|
586
801
|
const isAnimated = this._isAnimated();
|
587
802
|
|
588
|
-
const modalBody = SelectorEngine__default
|
803
|
+
const modalBody = SelectorEngine__default.default.findOne(SELECTOR_MODAL_BODY, this._dialog);
|
589
804
|
|
590
805
|
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
591
806
|
// Don't move modal's DOM position
|
592
|
-
document.body.
|
807
|
+
document.body.append(this._element);
|
593
808
|
}
|
594
809
|
|
595
810
|
this._element.style.display = 'block';
|
@@ -612,17 +827,13 @@
|
|
612
827
|
|
613
828
|
this._element.classList.add(CLASS_NAME_SHOW);
|
614
829
|
|
615
|
-
if (this._config.focus) {
|
616
|
-
this._enforceFocus();
|
617
|
-
}
|
618
|
-
|
619
830
|
const transitionComplete = () => {
|
620
831
|
if (this._config.focus) {
|
621
|
-
this.
|
832
|
+
this._focustrap.activate();
|
622
833
|
}
|
623
834
|
|
624
835
|
this._isTransitioning = false;
|
625
|
-
EventHandler__default
|
836
|
+
EventHandler__default.default.trigger(this._element, EVENT_SHOWN, {
|
626
837
|
relatedTarget
|
627
838
|
});
|
628
839
|
};
|
@@ -630,19 +841,9 @@
|
|
630
841
|
this._queueCallback(transitionComplete, this._dialog, isAnimated);
|
631
842
|
}
|
632
843
|
|
633
|
-
_enforceFocus() {
|
634
|
-
EventHandler__default['default'].off(document, EVENT_FOCUSIN); // guard against infinite focus loop
|
635
|
-
|
636
|
-
EventHandler__default['default'].on(document, EVENT_FOCUSIN, event => {
|
637
|
-
if (document !== event.target && this._element !== event.target && !this._element.contains(event.target)) {
|
638
|
-
this._element.focus();
|
639
|
-
}
|
640
|
-
});
|
641
|
-
}
|
642
|
-
|
643
844
|
_setEscapeEvent() {
|
644
845
|
if (this._isShown) {
|
645
|
-
EventHandler__default
|
846
|
+
EventHandler__default.default.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
646
847
|
if (this._config.keyboard && event.key === ESCAPE_KEY) {
|
647
848
|
event.preventDefault();
|
648
849
|
this.hide();
|
@@ -651,15 +852,15 @@
|
|
651
852
|
}
|
652
853
|
});
|
653
854
|
} else {
|
654
|
-
EventHandler__default
|
855
|
+
EventHandler__default.default.off(this._element, EVENT_KEYDOWN_DISMISS);
|
655
856
|
}
|
656
857
|
}
|
657
858
|
|
658
859
|
_setResizeEvent() {
|
659
860
|
if (this._isShown) {
|
660
|
-
EventHandler__default
|
861
|
+
EventHandler__default.default.on(window, EVENT_RESIZE, () => this._adjustDialog());
|
661
862
|
} else {
|
662
|
-
EventHandler__default
|
863
|
+
EventHandler__default.default.off(window, EVENT_RESIZE);
|
663
864
|
}
|
664
865
|
}
|
665
866
|
|
@@ -679,13 +880,14 @@
|
|
679
880
|
|
680
881
|
this._resetAdjustments();
|
681
882
|
|
682
|
-
reset();
|
683
|
-
|
883
|
+
this._scrollBar.reset();
|
884
|
+
|
885
|
+
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
|
684
886
|
});
|
685
887
|
}
|
686
888
|
|
687
889
|
_showBackdrop(callback) {
|
688
|
-
EventHandler__default
|
890
|
+
EventHandler__default.default.on(this._element, EVENT_CLICK_DISMISS, event => {
|
689
891
|
if (this._ignoreBackdropClick) {
|
690
892
|
this._ignoreBackdropClick = false;
|
691
893
|
return;
|
@@ -710,33 +912,38 @@
|
|
710
912
|
}
|
711
913
|
|
712
914
|
_triggerBackdropTransition() {
|
713
|
-
const hideEvent = EventHandler__default
|
915
|
+
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE_PREVENTED);
|
714
916
|
|
715
917
|
if (hideEvent.defaultPrevented) {
|
716
918
|
return;
|
717
919
|
}
|
718
920
|
|
719
|
-
const
|
921
|
+
const {
|
922
|
+
classList,
|
923
|
+
scrollHeight,
|
924
|
+
style
|
925
|
+
} = this._element;
|
926
|
+
const isModalOverflowing = scrollHeight > document.documentElement.clientHeight; // return if the following background transition hasn't yet completed
|
927
|
+
|
928
|
+
if (!isModalOverflowing && style.overflowY === 'hidden' || classList.contains(CLASS_NAME_STATIC)) {
|
929
|
+
return;
|
930
|
+
}
|
720
931
|
|
721
932
|
if (!isModalOverflowing) {
|
722
|
-
|
933
|
+
style.overflowY = 'hidden';
|
723
934
|
}
|
724
935
|
|
725
|
-
|
936
|
+
classList.add(CLASS_NAME_STATIC);
|
726
937
|
|
727
|
-
|
728
|
-
|
729
|
-
EventHandler__default['default'].one(this._element, 'transitionend', () => {
|
730
|
-
this._element.classList.remove(CLASS_NAME_STATIC);
|
938
|
+
this._queueCallback(() => {
|
939
|
+
classList.remove(CLASS_NAME_STATIC);
|
731
940
|
|
732
941
|
if (!isModalOverflowing) {
|
733
|
-
|
734
|
-
|
735
|
-
});
|
736
|
-
emulateTransitionEnd(this._element, modalTransitionDuration);
|
942
|
+
this._queueCallback(() => {
|
943
|
+
style.overflowY = '';
|
944
|
+
}, this._dialog);
|
737
945
|
}
|
738
|
-
});
|
739
|
-
emulateTransitionEnd(this._element, modalTransitionDuration);
|
946
|
+
}, this._dialog);
|
740
947
|
|
741
948
|
this._element.focus();
|
742
949
|
} // ----------------------------------------------------------------------
|
@@ -746,7 +953,9 @@
|
|
746
953
|
|
747
954
|
_adjustDialog() {
|
748
955
|
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
749
|
-
|
956
|
+
|
957
|
+
const scrollbarWidth = this._scrollBar.getWidth();
|
958
|
+
|
750
959
|
const isBodyOverflowing = scrollbarWidth > 0;
|
751
960
|
|
752
961
|
if (!isBodyOverflowing && isModalOverflowing && !isRTL() || isBodyOverflowing && !isModalOverflowing && isRTL()) {
|
@@ -766,7 +975,7 @@
|
|
766
975
|
|
767
976
|
static jQueryInterface(config, relatedTarget) {
|
768
977
|
return this.each(function () {
|
769
|
-
const data = Modal.
|
978
|
+
const data = Modal.getOrCreateInstance(this, config);
|
770
979
|
|
771
980
|
if (typeof config !== 'string') {
|
772
981
|
return;
|
@@ -788,28 +997,36 @@
|
|
788
997
|
*/
|
789
998
|
|
790
999
|
|
791
|
-
EventHandler__default
|
1000
|
+
EventHandler__default.default.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
792
1001
|
const target = getElementFromSelector(this);
|
793
1002
|
|
794
1003
|
if (['A', 'AREA'].includes(this.tagName)) {
|
795
1004
|
event.preventDefault();
|
796
1005
|
}
|
797
1006
|
|
798
|
-
EventHandler__default
|
1007
|
+
EventHandler__default.default.one(target, EVENT_SHOW, showEvent => {
|
799
1008
|
if (showEvent.defaultPrevented) {
|
800
1009
|
// only register focus restorer if modal will actually get shown
|
801
1010
|
return;
|
802
1011
|
}
|
803
1012
|
|
804
|
-
EventHandler__default
|
1013
|
+
EventHandler__default.default.one(target, EVENT_HIDDEN, () => {
|
805
1014
|
if (isVisible(this)) {
|
806
1015
|
this.focus();
|
807
1016
|
}
|
808
1017
|
});
|
809
|
-
});
|
810
|
-
|
1018
|
+
}); // avoid conflict when clicking moddal toggler while another one is open
|
1019
|
+
|
1020
|
+
const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR);
|
1021
|
+
|
1022
|
+
if (allReadyOpen) {
|
1023
|
+
Modal.getInstance(allReadyOpen).hide();
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
const data = Modal.getOrCreateInstance(target);
|
811
1027
|
data.toggle(this);
|
812
1028
|
});
|
1029
|
+
enableDismissTrigger(Modal);
|
813
1030
|
/**
|
814
1031
|
* ------------------------------------------------------------------------
|
815
1032
|
* jQuery
|
@@ -821,4 +1038,4 @@
|
|
821
1038
|
|
822
1039
|
return Modal;
|
823
1040
|
|
824
|
-
}))
|
1041
|
+
}));
|