bootstrap 5.0.0 → 5.1.1
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/assets/javascripts/bootstrap/alert.js +77 -106
- data/assets/javascripts/bootstrap/base-component.js +126 -7
- data/assets/javascripts/bootstrap/button.js +24 -24
- data/assets/javascripts/bootstrap/carousel.js +115 -128
- data/assets/javascripts/bootstrap/collapse.js +119 -176
- data/assets/javascripts/bootstrap/dom/data.js +2 -2
- data/assets/javascripts/bootstrap/dom/event-handler.js +3 -4
- data/assets/javascripts/bootstrap/dom/manipulator.js +4 -4
- data/assets/javascripts/bootstrap/dom/selector-engine.js +47 -5
- data/assets/javascripts/bootstrap/dropdown.js +142 -130
- data/assets/javascripts/bootstrap/modal.js +376 -171
- data/assets/javascripts/bootstrap/offcanvas.js +328 -133
- data/assets/javascripts/bootstrap/popover.js +27 -59
- data/assets/javascripts/bootstrap/scrollspy.js +51 -56
- data/assets/javascripts/bootstrap/tab.js +39 -66
- data/assets/javascripts/bootstrap/toast.js +175 -86
- data/assets/javascripts/bootstrap/tooltip.js +141 -185
- data/assets/javascripts/bootstrap-sprockets.js +6 -6
- data/assets/javascripts/bootstrap.js +1031 -1026
- 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/_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/_list-group.scss +5 -5
- data/assets/stylesheets/bootstrap/_mixins.scss +1 -0
- data/assets/stylesheets/bootstrap/_modal.scss +7 -26
- 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 +1 -0
- 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 +200 -25
- 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 +6 -6
- data/assets/stylesheets/bootstrap/forms/_form-range.scss +1 -1
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +3 -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/_forms.scss +8 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +33 -8
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +27 -6
- 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,25 +1,24 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap offcanvas.js v5.
|
2
|
+
* Bootstrap offcanvas.js v5.1.1 (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/selector-engine.js'), require('./dom/manipulator.js'), require('./dom/
|
8
|
-
typeof define === 'function' && define.amd ? define(['./dom/selector-engine', './dom/manipulator', './dom/
|
9
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.SelectorEngine, global.Manipulator, global.
|
10
|
-
}(this, (function (SelectorEngine, Manipulator,
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/selector-engine.js'), require('./dom/manipulator.js'), require('./dom/event-handler.js'), require('./base-component.js')) :
|
8
|
+
typeof define === 'function' && define.amd ? define(['./dom/selector-engine', './dom/manipulator', './dom/event-handler', './base-component'], factory) :
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.SelectorEngine, global.Manipulator, global.EventHandler, global.Base));
|
10
|
+
}(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict';
|
11
11
|
|
12
12
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
13
13
|
|
14
14
|
var SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
15
15
|
var Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
16
|
-
var Data__default = /*#__PURE__*/_interopDefaultLegacy(Data);
|
17
16
|
var EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
18
17
|
var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
19
18
|
|
20
19
|
/**
|
21
20
|
* --------------------------------------------------------------------------
|
22
|
-
* Bootstrap (v5.
|
21
|
+
* Bootstrap (v5.1.1): util/index.js
|
23
22
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
24
23
|
* --------------------------------------------------------------------------
|
25
24
|
*/
|
@@ -90,24 +89,29 @@
|
|
90
89
|
element.dispatchEvent(new Event(TRANSITION_END));
|
91
90
|
};
|
92
91
|
|
93
|
-
const isElement = obj =>
|
92
|
+
const isElement = obj => {
|
93
|
+
if (!obj || typeof obj !== 'object') {
|
94
|
+
return false;
|
95
|
+
}
|
94
96
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
const emulatedDuration = duration + durationPadding;
|
97
|
+
if (typeof obj.jquery !== 'undefined') {
|
98
|
+
obj = obj[0];
|
99
|
+
}
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
101
|
+
return typeof obj.nodeType !== 'undefined';
|
102
|
+
};
|
103
|
+
|
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;
|
103
108
|
}
|
104
109
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
}, emulatedDuration);
|
110
|
+
if (typeof obj === 'string' && obj.length > 0) {
|
111
|
+
return document.querySelector(obj);
|
112
|
+
}
|
113
|
+
|
114
|
+
return null;
|
111
115
|
};
|
112
116
|
|
113
117
|
const typeCheckConfig = (componentName, config, configTypes) => {
|
@@ -123,17 +127,11 @@
|
|
123
127
|
};
|
124
128
|
|
125
129
|
const isVisible = element => {
|
126
|
-
if (!element) {
|
130
|
+
if (!isElement(element) || element.getClientRects().length === 0) {
|
127
131
|
return false;
|
128
132
|
}
|
129
133
|
|
130
|
-
|
131
|
-
const elementStyle = getComputedStyle(element);
|
132
|
-
const parentNodeStyle = getComputedStyle(element.parentNode);
|
133
|
-
return elementStyle.display !== 'none' && parentNodeStyle.display !== 'none' && elementStyle.visibility !== 'hidden';
|
134
|
-
}
|
135
|
-
|
136
|
-
return false;
|
134
|
+
return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
137
135
|
};
|
138
136
|
|
139
137
|
const isDisabled = element => {
|
@@ -151,8 +149,20 @@
|
|
151
149
|
|
152
150
|
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
153
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
|
+
|
154
161
|
|
155
|
-
const reflow = element =>
|
162
|
+
const reflow = element => {
|
163
|
+
// eslint-disable-next-line no-unused-expressions
|
164
|
+
element.offsetHeight;
|
165
|
+
};
|
156
166
|
|
157
167
|
const getjQuery = () => {
|
158
168
|
const {
|
@@ -166,20 +176,30 @@
|
|
166
176
|
return null;
|
167
177
|
};
|
168
178
|
|
179
|
+
const DOMContentLoadedCallbacks = [];
|
180
|
+
|
169
181
|
const onDOMContentLoaded = callback => {
|
170
182
|
if (document.readyState === 'loading') {
|
171
|
-
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);
|
172
191
|
} else {
|
173
192
|
callback();
|
174
193
|
}
|
175
194
|
};
|
176
195
|
|
177
|
-
const defineJQueryPlugin =
|
196
|
+
const defineJQueryPlugin = plugin => {
|
178
197
|
onDOMContentLoaded(() => {
|
179
198
|
const $ = getjQuery();
|
180
199
|
/* istanbul ignore if */
|
181
200
|
|
182
201
|
if ($) {
|
202
|
+
const name = plugin.NAME;
|
183
203
|
const JQUERY_NO_CONFLICT = $.fn[name];
|
184
204
|
$.fn[name] = plugin.jQueryInterface;
|
185
205
|
$.fn[name].Constructor = plugin;
|
@@ -198,105 +218,166 @@
|
|
198
218
|
}
|
199
219
|
};
|
200
220
|
|
221
|
+
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
222
|
+
if (!waitForTransition) {
|
223
|
+
execute(callback);
|
224
|
+
return;
|
225
|
+
}
|
226
|
+
|
227
|
+
const durationPadding = 5;
|
228
|
+
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
229
|
+
let called = false;
|
230
|
+
|
231
|
+
const handler = ({
|
232
|
+
target
|
233
|
+
}) => {
|
234
|
+
if (target !== transitionElement) {
|
235
|
+
return;
|
236
|
+
}
|
237
|
+
|
238
|
+
called = true;
|
239
|
+
transitionElement.removeEventListener(TRANSITION_END, handler);
|
240
|
+
execute(callback);
|
241
|
+
};
|
242
|
+
|
243
|
+
transitionElement.addEventListener(TRANSITION_END, handler);
|
244
|
+
setTimeout(() => {
|
245
|
+
if (!called) {
|
246
|
+
triggerTransitionEnd(transitionElement);
|
247
|
+
}
|
248
|
+
}, emulatedDuration);
|
249
|
+
};
|
250
|
+
|
201
251
|
/**
|
202
252
|
* --------------------------------------------------------------------------
|
203
|
-
* Bootstrap (v5.
|
253
|
+
* Bootstrap (v5.1.1): util/scrollBar.js
|
204
254
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
205
255
|
* --------------------------------------------------------------------------
|
206
256
|
*/
|
207
257
|
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
208
258
|
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
209
259
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
};
|
260
|
+
class ScrollBarHelper {
|
261
|
+
constructor() {
|
262
|
+
this._element = document.body;
|
263
|
+
}
|
215
264
|
|
216
|
-
|
217
|
-
|
265
|
+
getWidth() {
|
266
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
267
|
+
const documentWidth = document.documentElement.clientWidth;
|
268
|
+
return Math.abs(window.innerWidth - documentWidth);
|
269
|
+
}
|
218
270
|
|
271
|
+
hide() {
|
272
|
+
const width = this.getWidth();
|
219
273
|
|
220
|
-
|
274
|
+
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
|
221
275
|
|
222
276
|
|
223
|
-
|
277
|
+
this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
224
278
|
|
225
|
-
_setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
226
|
-
};
|
227
279
|
|
228
|
-
|
229
|
-
const actualValue = document.body.style.overflow;
|
280
|
+
this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
|
230
281
|
|
231
|
-
|
232
|
-
Manipulator__default['default'].setDataAttribute(document.body, 'overflow', actualValue);
|
282
|
+
this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
233
283
|
}
|
234
284
|
|
235
|
-
|
236
|
-
|
285
|
+
_disableOverFlow() {
|
286
|
+
this._saveInitialAttribute(this._element, 'overflow');
|
237
287
|
|
238
|
-
|
239
|
-
|
240
|
-
SelectorEngine__default['default'].find(selector).forEach(element => {
|
241
|
-
if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
242
|
-
return;
|
243
|
-
}
|
288
|
+
this._element.style.overflow = 'hidden';
|
289
|
+
}
|
244
290
|
|
245
|
-
|
246
|
-
const
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
291
|
+
_setElementAttributes(selector, styleProp, callback) {
|
292
|
+
const scrollbarWidth = this.getWidth();
|
293
|
+
|
294
|
+
const manipulationCallBack = element => {
|
295
|
+
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
296
|
+
return;
|
297
|
+
}
|
251
298
|
|
252
|
-
|
253
|
-
_resetElementAttributes('body', 'overflow');
|
299
|
+
this._saveInitialAttribute(element, styleProp);
|
254
300
|
|
255
|
-
|
301
|
+
const calculatedValue = window.getComputedStyle(element)[styleProp];
|
302
|
+
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
|
303
|
+
};
|
256
304
|
|
257
|
-
|
305
|
+
this._applyManipulationCallback(selector, manipulationCallBack);
|
306
|
+
}
|
258
307
|
|
259
|
-
|
260
|
-
|
308
|
+
reset() {
|
309
|
+
this._resetElementAttributes(this._element, 'overflow');
|
261
310
|
|
262
|
-
|
263
|
-
SelectorEngine__default['default'].find(selector).forEach(element => {
|
264
|
-
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
|
311
|
+
this._resetElementAttributes(this._element, 'paddingRight');
|
265
312
|
|
266
|
-
|
267
|
-
|
313
|
+
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
|
314
|
+
|
315
|
+
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
|
316
|
+
}
|
317
|
+
|
318
|
+
_saveInitialAttribute(element, styleProp) {
|
319
|
+
const actualValue = element.style[styleProp];
|
320
|
+
|
321
|
+
if (actualValue) {
|
322
|
+
Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
_resetElementAttributes(selector, styleProp) {
|
327
|
+
const manipulationCallBack = element => {
|
328
|
+
const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
|
329
|
+
|
330
|
+
if (typeof value === 'undefined') {
|
331
|
+
element.style.removeProperty(styleProp);
|
332
|
+
} else {
|
333
|
+
Manipulator__default['default'].removeDataAttribute(element, styleProp);
|
334
|
+
element.style[styleProp] = value;
|
335
|
+
}
|
336
|
+
};
|
337
|
+
|
338
|
+
this._applyManipulationCallback(selector, manipulationCallBack);
|
339
|
+
}
|
340
|
+
|
341
|
+
_applyManipulationCallback(selector, callBack) {
|
342
|
+
if (isElement(selector)) {
|
343
|
+
callBack(selector);
|
268
344
|
} else {
|
269
|
-
|
270
|
-
element.style[styleProp] = value;
|
345
|
+
SelectorEngine__default['default'].find(selector, this._element).forEach(callBack);
|
271
346
|
}
|
272
|
-
}
|
273
|
-
|
347
|
+
}
|
348
|
+
|
349
|
+
isOverflowing() {
|
350
|
+
return this.getWidth() > 0;
|
351
|
+
}
|
352
|
+
|
353
|
+
}
|
274
354
|
|
275
355
|
/**
|
276
356
|
* --------------------------------------------------------------------------
|
277
|
-
* Bootstrap (v5.
|
357
|
+
* Bootstrap (v5.1.1): util/backdrop.js
|
278
358
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
279
359
|
* --------------------------------------------------------------------------
|
280
360
|
*/
|
281
|
-
const Default$
|
361
|
+
const Default$2 = {
|
362
|
+
className: 'modal-backdrop',
|
282
363
|
isVisible: true,
|
283
364
|
// if false, we use the backdrop helper without adding any element to the dom
|
284
365
|
isAnimated: false,
|
285
|
-
rootElement:
|
366
|
+
rootElement: 'body',
|
286
367
|
// give the choice to place backdrop under different elements
|
287
368
|
clickCallback: null
|
288
369
|
};
|
289
|
-
const DefaultType$
|
370
|
+
const DefaultType$2 = {
|
371
|
+
className: 'string',
|
290
372
|
isVisible: 'boolean',
|
291
373
|
isAnimated: 'boolean',
|
292
|
-
rootElement: 'element',
|
374
|
+
rootElement: '(element|string)',
|
293
375
|
clickCallback: '(function|null)'
|
294
376
|
};
|
295
|
-
const NAME$
|
296
|
-
const CLASS_NAME_BACKDROP = 'modal-backdrop';
|
377
|
+
const NAME$2 = 'backdrop';
|
297
378
|
const CLASS_NAME_FADE = 'fade';
|
298
379
|
const CLASS_NAME_SHOW$1 = 'show';
|
299
|
-
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$
|
380
|
+
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
|
300
381
|
|
301
382
|
class Backdrop {
|
302
383
|
constructor(config) {
|
@@ -342,7 +423,7 @@
|
|
342
423
|
_getElement() {
|
343
424
|
if (!this._element) {
|
344
425
|
const backdrop = document.createElement('div');
|
345
|
-
backdrop.className =
|
426
|
+
backdrop.className = this._config.className;
|
346
427
|
|
347
428
|
if (this._config.isAnimated) {
|
348
429
|
backdrop.classList.add(CLASS_NAME_FADE);
|
@@ -355,10 +436,12 @@
|
|
355
436
|
}
|
356
437
|
|
357
438
|
_getConfig(config) {
|
358
|
-
config = { ...Default$
|
439
|
+
config = { ...Default$2,
|
359
440
|
...(typeof config === 'object' ? config : {})
|
360
|
-
};
|
361
|
-
|
441
|
+
}; // use getElement() with the default "body" to get a fresh Element on each instantiation
|
442
|
+
|
443
|
+
config.rootElement = getElement(config.rootElement);
|
444
|
+
typeCheckConfig(NAME$2, config, DefaultType$2);
|
362
445
|
return config;
|
363
446
|
}
|
364
447
|
|
@@ -367,7 +450,7 @@
|
|
367
450
|
return;
|
368
451
|
}
|
369
452
|
|
370
|
-
this._config.rootElement.
|
453
|
+
this._config.rootElement.append(this._getElement());
|
371
454
|
|
372
455
|
EventHandler__default['default'].on(this._getElement(), EVENT_MOUSEDOWN, () => {
|
373
456
|
execute(this._config.clickCallback);
|
@@ -382,27 +465,149 @@
|
|
382
465
|
|
383
466
|
EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
|
384
467
|
|
385
|
-
this.
|
468
|
+
this._element.remove();
|
386
469
|
|
387
470
|
this._isAppended = false;
|
388
471
|
}
|
389
472
|
|
390
473
|
_emulateAnimation(callback) {
|
391
|
-
|
392
|
-
|
474
|
+
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
475
|
+
}
|
476
|
+
|
477
|
+
}
|
478
|
+
|
479
|
+
/**
|
480
|
+
* --------------------------------------------------------------------------
|
481
|
+
* Bootstrap (v5.1.1): util/focustrap.js
|
482
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
483
|
+
* --------------------------------------------------------------------------
|
484
|
+
*/
|
485
|
+
const Default$1 = {
|
486
|
+
trapElement: null,
|
487
|
+
// The element to trap focus inside of
|
488
|
+
autofocus: true
|
489
|
+
};
|
490
|
+
const DefaultType$1 = {
|
491
|
+
trapElement: 'element',
|
492
|
+
autofocus: 'boolean'
|
493
|
+
};
|
494
|
+
const NAME$1 = 'focustrap';
|
495
|
+
const DATA_KEY$1 = 'bs.focustrap';
|
496
|
+
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
497
|
+
const EVENT_FOCUSIN = `focusin${EVENT_KEY$1}`;
|
498
|
+
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$1}`;
|
499
|
+
const TAB_KEY = 'Tab';
|
500
|
+
const TAB_NAV_FORWARD = 'forward';
|
501
|
+
const TAB_NAV_BACKWARD = 'backward';
|
502
|
+
|
503
|
+
class FocusTrap {
|
504
|
+
constructor(config) {
|
505
|
+
this._config = this._getConfig(config);
|
506
|
+
this._isActive = false;
|
507
|
+
this._lastTabNavDirection = null;
|
508
|
+
}
|
509
|
+
|
510
|
+
activate() {
|
511
|
+
const {
|
512
|
+
trapElement,
|
513
|
+
autofocus
|
514
|
+
} = this._config;
|
515
|
+
|
516
|
+
if (this._isActive) {
|
517
|
+
return;
|
518
|
+
}
|
519
|
+
|
520
|
+
if (autofocus) {
|
521
|
+
trapElement.focus();
|
522
|
+
}
|
523
|
+
|
524
|
+
EventHandler__default['default'].off(document, EVENT_KEY$1); // guard against infinite focus loop
|
525
|
+
|
526
|
+
EventHandler__default['default'].on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
|
527
|
+
EventHandler__default['default'].on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
528
|
+
this._isActive = true;
|
529
|
+
}
|
530
|
+
|
531
|
+
deactivate() {
|
532
|
+
if (!this._isActive) {
|
533
|
+
return;
|
534
|
+
}
|
535
|
+
|
536
|
+
this._isActive = false;
|
537
|
+
EventHandler__default['default'].off(document, EVENT_KEY$1);
|
538
|
+
} // Private
|
539
|
+
|
540
|
+
|
541
|
+
_handleFocusin(event) {
|
542
|
+
const {
|
543
|
+
target
|
544
|
+
} = event;
|
545
|
+
const {
|
546
|
+
trapElement
|
547
|
+
} = this._config;
|
548
|
+
|
549
|
+
if (target === document || target === trapElement || trapElement.contains(target)) {
|
550
|
+
return;
|
551
|
+
}
|
552
|
+
|
553
|
+
const elements = SelectorEngine__default['default'].focusableChildren(trapElement);
|
554
|
+
|
555
|
+
if (elements.length === 0) {
|
556
|
+
trapElement.focus();
|
557
|
+
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
558
|
+
elements[elements.length - 1].focus();
|
559
|
+
} else {
|
560
|
+
elements[0].focus();
|
561
|
+
}
|
562
|
+
}
|
563
|
+
|
564
|
+
_handleKeydown(event) {
|
565
|
+
if (event.key !== TAB_KEY) {
|
393
566
|
return;
|
394
567
|
}
|
395
568
|
|
396
|
-
|
397
|
-
|
398
|
-
|
569
|
+
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
570
|
+
}
|
571
|
+
|
572
|
+
_getConfig(config) {
|
573
|
+
config = { ...Default$1,
|
574
|
+
...(typeof config === 'object' ? config : {})
|
575
|
+
};
|
576
|
+
typeCheckConfig(NAME$1, config, DefaultType$1);
|
577
|
+
return config;
|
399
578
|
}
|
400
579
|
|
401
580
|
}
|
402
581
|
|
403
582
|
/**
|
404
583
|
* --------------------------------------------------------------------------
|
405
|
-
* Bootstrap (v5.
|
584
|
+
* Bootstrap (v5.1.1): util/component-functions.js
|
585
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
586
|
+
* --------------------------------------------------------------------------
|
587
|
+
*/
|
588
|
+
|
589
|
+
const enableDismissTrigger = (component, method = 'hide') => {
|
590
|
+
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
591
|
+
const name = component.NAME;
|
592
|
+
EventHandler__default['default'].on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
593
|
+
if (['A', 'AREA'].includes(this.tagName)) {
|
594
|
+
event.preventDefault();
|
595
|
+
}
|
596
|
+
|
597
|
+
if (isDisabled(this)) {
|
598
|
+
return;
|
599
|
+
}
|
600
|
+
|
601
|
+
const target = getElementFromSelector(this) || this.closest(`.${name}`);
|
602
|
+
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
603
|
+
|
604
|
+
instance[method]();
|
605
|
+
});
|
606
|
+
};
|
607
|
+
|
608
|
+
/**
|
609
|
+
* --------------------------------------------------------------------------
|
610
|
+
* Bootstrap (v5.1.1): offcanvas.js
|
406
611
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
407
612
|
* --------------------------------------------------------------------------
|
408
613
|
*/
|
@@ -429,16 +634,14 @@
|
|
429
634
|
scroll: 'boolean'
|
430
635
|
};
|
431
636
|
const CLASS_NAME_SHOW = 'show';
|
637
|
+
const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
|
432
638
|
const OPEN_SELECTOR = '.offcanvas.show';
|
433
639
|
const EVENT_SHOW = `show${EVENT_KEY}`;
|
434
640
|
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
435
641
|
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
436
642
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
437
|
-
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
|
438
643
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
439
|
-
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
|
440
644
|
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
441
|
-
const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="offcanvas"]';
|
442
645
|
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
|
443
646
|
/**
|
444
647
|
* ------------------------------------------------------------------------
|
@@ -452,17 +655,18 @@
|
|
452
655
|
this._config = this._getConfig(config);
|
453
656
|
this._isShown = false;
|
454
657
|
this._backdrop = this._initializeBackDrop();
|
658
|
+
this._focustrap = this._initializeFocusTrap();
|
455
659
|
|
456
660
|
this._addEventListeners();
|
457
661
|
} // Getters
|
458
662
|
|
459
663
|
|
460
|
-
static get
|
461
|
-
return
|
664
|
+
static get NAME() {
|
665
|
+
return NAME;
|
462
666
|
}
|
463
667
|
|
464
|
-
static get
|
465
|
-
return
|
668
|
+
static get Default() {
|
669
|
+
return Default;
|
466
670
|
} // Public
|
467
671
|
|
468
672
|
|
@@ -489,9 +693,7 @@
|
|
489
693
|
this._backdrop.show();
|
490
694
|
|
491
695
|
if (!this._config.scroll) {
|
492
|
-
hide();
|
493
|
-
|
494
|
-
this._enforceFocusOnElement(this._element);
|
696
|
+
new ScrollBarHelper().hide();
|
495
697
|
}
|
496
698
|
|
497
699
|
this._element.removeAttribute('aria-hidden');
|
@@ -503,14 +705,16 @@
|
|
503
705
|
this._element.classList.add(CLASS_NAME_SHOW);
|
504
706
|
|
505
707
|
const completeCallBack = () => {
|
708
|
+
if (!this._config.scroll) {
|
709
|
+
this._focustrap.activate();
|
710
|
+
}
|
711
|
+
|
506
712
|
EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, {
|
507
713
|
relatedTarget
|
508
714
|
});
|
509
715
|
};
|
510
716
|
|
511
|
-
|
512
|
-
EventHandler__default['default'].one(this._element, 'transitionend', completeCallBack);
|
513
|
-
emulateTransitionEnd(this._element, transitionDuration);
|
717
|
+
this._queueCallback(completeCallBack, this._element, true);
|
514
718
|
}
|
515
719
|
|
516
720
|
hide() {
|
@@ -524,7 +728,7 @@
|
|
524
728
|
return;
|
525
729
|
}
|
526
730
|
|
527
|
-
|
731
|
+
this._focustrap.deactivate();
|
528
732
|
|
529
733
|
this._element.blur();
|
530
734
|
|
@@ -544,24 +748,21 @@
|
|
544
748
|
this._element.style.visibility = 'hidden';
|
545
749
|
|
546
750
|
if (!this._config.scroll) {
|
547
|
-
reset();
|
751
|
+
new ScrollBarHelper().reset();
|
548
752
|
}
|
549
753
|
|
550
754
|
EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
|
551
755
|
};
|
552
756
|
|
553
|
-
|
554
|
-
EventHandler__default['default'].one(this._element, 'transitionend', completeCallback);
|
555
|
-
emulateTransitionEnd(this._element, transitionDuration);
|
757
|
+
this._queueCallback(completeCallback, this._element, true);
|
556
758
|
}
|
557
759
|
|
558
760
|
dispose() {
|
559
761
|
this._backdrop.dispose();
|
560
762
|
|
763
|
+
this._focustrap.deactivate();
|
764
|
+
|
561
765
|
super.dispose();
|
562
|
-
EventHandler__default['default'].off(document, EVENT_FOCUSIN);
|
563
|
-
this._config = null;
|
564
|
-
this._backdrop = null;
|
565
766
|
} // Private
|
566
767
|
|
567
768
|
|
@@ -576,6 +777,7 @@
|
|
576
777
|
|
577
778
|
_initializeBackDrop() {
|
578
779
|
return new Backdrop({
|
780
|
+
className: CLASS_NAME_BACKDROP,
|
579
781
|
isVisible: this._config.backdrop,
|
580
782
|
isAnimated: true,
|
581
783
|
rootElement: this._element.parentNode,
|
@@ -583,19 +785,13 @@
|
|
583
785
|
});
|
584
786
|
}
|
585
787
|
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
EventHandler__default['default'].on(document, EVENT_FOCUSIN, event => {
|
590
|
-
if (document !== event.target && element !== event.target && !element.contains(event.target)) {
|
591
|
-
element.focus();
|
592
|
-
}
|
788
|
+
_initializeFocusTrap() {
|
789
|
+
return new FocusTrap({
|
790
|
+
trapElement: this._element
|
593
791
|
});
|
594
|
-
element.focus();
|
595
792
|
}
|
596
793
|
|
597
794
|
_addEventListeners() {
|
598
|
-
EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
|
599
795
|
EventHandler__default['default'].on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
600
796
|
if (this._config.keyboard && event.key === ESCAPE_KEY) {
|
601
797
|
this.hide();
|
@@ -606,7 +802,7 @@
|
|
606
802
|
|
607
803
|
static jQueryInterface(config) {
|
608
804
|
return this.each(function () {
|
609
|
-
const data =
|
805
|
+
const data = Offcanvas.getOrCreateInstance(this, config);
|
610
806
|
|
611
807
|
if (typeof config !== 'string') {
|
612
808
|
return;
|
@@ -652,19 +848,18 @@
|
|
652
848
|
Offcanvas.getInstance(allReadyOpen).hide();
|
653
849
|
}
|
654
850
|
|
655
|
-
const data =
|
851
|
+
const data = Offcanvas.getOrCreateInstance(target);
|
656
852
|
data.toggle(this);
|
657
853
|
});
|
658
|
-
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () =>
|
659
|
-
|
660
|
-
});
|
854
|
+
EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default['default'].find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));
|
855
|
+
enableDismissTrigger(Offcanvas);
|
661
856
|
/**
|
662
857
|
* ------------------------------------------------------------------------
|
663
858
|
* jQuery
|
664
859
|
* ------------------------------------------------------------------------
|
665
860
|
*/
|
666
861
|
|
667
|
-
defineJQueryPlugin(
|
862
|
+
defineJQueryPlugin(Offcanvas);
|
668
863
|
|
669
864
|
return Offcanvas;
|
670
865
|
|