bootstrap 5.1.3 → 5.2.2
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 +24 -4
- data/assets/javascripts/bootstrap/alert.js +11 -146
- data/assets/javascripts/bootstrap/base-component.js +37 -120
- data/assets/javascripts/bootstrap/button.js +10 -74
- data/assets/javascripts/bootstrap/carousel.js +213 -485
- data/assets/javascripts/bootstrap/collapse.js +65 -249
- data/assets/javascripts/bootstrap/dom/data.js +3 -5
- data/assets/javascripts/bootstrap/dom/event-handler.js +94 -132
- data/assets/javascripts/bootstrap/dom/manipulator.js +23 -27
- data/assets/javascripts/bootstrap/dom/selector-engine.js +16 -58
- data/assets/javascripts/bootstrap/dropdown.js +103 -317
- data/assets/javascripts/bootstrap/modal.js +107 -749
- data/assets/javascripts/bootstrap/offcanvas.js +90 -659
- data/assets/javascripts/bootstrap/popover.js +36 -118
- data/assets/javascripts/bootstrap/scrollspy.js +183 -262
- data/assets/javascripts/bootstrap/tab.js +215 -214
- data/assets/javascripts/bootstrap/toast.js +36 -218
- data/assets/javascripts/bootstrap/tooltip.js +280 -629
- data/assets/javascripts/bootstrap/util/backdrop.js +165 -0
- data/assets/javascripts/bootstrap/util/component-functions.js +46 -0
- data/assets/javascripts/bootstrap/util/config.js +79 -0
- data/assets/javascripts/bootstrap/util/focustrap.js +129 -0
- data/assets/javascripts/bootstrap/util/index.js +350 -0
- data/assets/javascripts/bootstrap/util/sanitizer.js +122 -0
- data/assets/javascripts/bootstrap/util/scrollbar.js +138 -0
- data/assets/javascripts/bootstrap/util/swipe.js +155 -0
- data/assets/javascripts/bootstrap/util/template-factory.js +177 -0
- data/assets/javascripts/bootstrap-global-this-define.js +1 -1
- data/assets/javascripts/bootstrap-sprockets.js +17 -8
- data/assets/javascripts/bootstrap.js +2093 -1881
- data/assets/javascripts/bootstrap.min.js +3 -3
- data/assets/stylesheets/_bootstrap-grid.scss +3 -6
- data/assets/stylesheets/_bootstrap-reboot.scss +3 -7
- data/assets/stylesheets/_bootstrap.scss +4 -6
- data/assets/stylesheets/bootstrap/_accordion.scss +56 -25
- data/assets/stylesheets/bootstrap/_alert.scss +18 -4
- data/assets/stylesheets/bootstrap/_badge.scss +14 -5
- data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
- data/assets/stylesheets/bootstrap/_button-group.scss +4 -1
- data/assets/stylesheets/bootstrap/_buttons.scss +125 -29
- data/assets/stylesheets/bootstrap/_card.scss +55 -37
- data/assets/stylesheets/bootstrap/_close.scss +1 -1
- data/assets/stylesheets/bootstrap/_containers.scss +1 -1
- data/assets/stylesheets/bootstrap/_dropdown.scss +85 -76
- data/assets/stylesheets/bootstrap/_functions.scss +8 -8
- data/assets/stylesheets/bootstrap/_grid.scss +3 -3
- data/assets/stylesheets/bootstrap/_helpers.scss +1 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +48 -30
- data/assets/stylesheets/bootstrap/_maps.scss +54 -0
- data/assets/stylesheets/bootstrap/_modal.scss +71 -43
- data/assets/stylesheets/bootstrap/_nav.scss +53 -20
- data/assets/stylesheets/bootstrap/_navbar.scss +93 -150
- data/assets/stylesheets/bootstrap/_offcanvas.scss +120 -59
- data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
- data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
- data/assets/stylesheets/bootstrap/_popover.scss +90 -52
- data/assets/stylesheets/bootstrap/_progress.scss +20 -9
- data/assets/stylesheets/bootstrap/_reboot.scss +25 -40
- data/assets/stylesheets/bootstrap/_root.scss +40 -21
- data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
- data/assets/stylesheets/bootstrap/_tables.scss +32 -23
- data/assets/stylesheets/bootstrap/_toasts.scss +38 -16
- data/assets/stylesheets/bootstrap/_tooltip.scss +61 -56
- data/assets/stylesheets/bootstrap/_type.scss +2 -0
- data/assets/stylesheets/bootstrap/_utilities.scss +43 -26
- data/assets/stylesheets/bootstrap/_variables.scss +128 -135
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +3 -6
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +15 -3
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +28 -5
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +12 -37
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +0 -1
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +19 -8
- data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +10 -0
- data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +2 -2
- data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
- data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
- data/assets/stylesheets/bootstrap/helpers/_vr.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_alert.scss +7 -3
- data/assets/stylesheets/bootstrap/mixins/_banner.scss +9 -0
- data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
- data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
- data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
- data/assets/stylesheets/bootstrap/mixins/_forms.scss +18 -10
- data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +12 -12
- data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
- data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +13 -5
- data/bootstrap.gemspec +1 -1
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +10 -5
- data/tasks/updater.rb +2 -2
- metadata +16 -4
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Bootstrap backdrop.js v5.2.2 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler'), require('./index'), require('./config')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['../dom/event-handler', './index', './config'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Backdrop = factory(global.EventHandler, global.Index, global.Config));
|
|
10
|
+
})(this, (function (EventHandler, index, Config) { 'use strict';
|
|
11
|
+
|
|
12
|
+
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
|
+
|
|
14
|
+
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
+
const Config__default = /*#__PURE__*/_interopDefaultLegacy(Config);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* --------------------------------------------------------------------------
|
|
19
|
+
* Bootstrap (v5.2.2): util/backdrop.js
|
|
20
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
21
|
+
* --------------------------------------------------------------------------
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Constants
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const NAME = 'backdrop';
|
|
28
|
+
const CLASS_NAME_FADE = 'fade';
|
|
29
|
+
const CLASS_NAME_SHOW = 'show';
|
|
30
|
+
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME}`;
|
|
31
|
+
const Default = {
|
|
32
|
+
className: 'modal-backdrop',
|
|
33
|
+
clickCallback: null,
|
|
34
|
+
isAnimated: false,
|
|
35
|
+
isVisible: true,
|
|
36
|
+
// if false, we use the backdrop helper without adding any element to the dom
|
|
37
|
+
rootElement: 'body' // give the choice to place backdrop under different elements
|
|
38
|
+
|
|
39
|
+
};
|
|
40
|
+
const DefaultType = {
|
|
41
|
+
className: 'string',
|
|
42
|
+
clickCallback: '(function|null)',
|
|
43
|
+
isAnimated: 'boolean',
|
|
44
|
+
isVisible: 'boolean',
|
|
45
|
+
rootElement: '(element|string)'
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Class definition
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
class Backdrop extends Config__default.default {
|
|
52
|
+
constructor(config) {
|
|
53
|
+
super();
|
|
54
|
+
this._config = this._getConfig(config);
|
|
55
|
+
this._isAppended = false;
|
|
56
|
+
this._element = null;
|
|
57
|
+
} // Getters
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
static get Default() {
|
|
61
|
+
return Default;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static get DefaultType() {
|
|
65
|
+
return DefaultType;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static get NAME() {
|
|
69
|
+
return NAME;
|
|
70
|
+
} // Public
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
show(callback) {
|
|
74
|
+
if (!this._config.isVisible) {
|
|
75
|
+
index.execute(callback);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this._append();
|
|
80
|
+
|
|
81
|
+
const element = this._getElement();
|
|
82
|
+
|
|
83
|
+
if (this._config.isAnimated) {
|
|
84
|
+
index.reflow(element);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
element.classList.add(CLASS_NAME_SHOW);
|
|
88
|
+
|
|
89
|
+
this._emulateAnimation(() => {
|
|
90
|
+
index.execute(callback);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
hide(callback) {
|
|
95
|
+
if (!this._config.isVisible) {
|
|
96
|
+
index.execute(callback);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this._getElement().classList.remove(CLASS_NAME_SHOW);
|
|
101
|
+
|
|
102
|
+
this._emulateAnimation(() => {
|
|
103
|
+
this.dispose();
|
|
104
|
+
index.execute(callback);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
dispose() {
|
|
109
|
+
if (!this._isAppended) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
|
|
114
|
+
|
|
115
|
+
this._element.remove();
|
|
116
|
+
|
|
117
|
+
this._isAppended = false;
|
|
118
|
+
} // Private
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
_getElement() {
|
|
122
|
+
if (!this._element) {
|
|
123
|
+
const backdrop = document.createElement('div');
|
|
124
|
+
backdrop.className = this._config.className;
|
|
125
|
+
|
|
126
|
+
if (this._config.isAnimated) {
|
|
127
|
+
backdrop.classList.add(CLASS_NAME_FADE);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this._element = backdrop;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return this._element;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
_configAfterMerge(config) {
|
|
137
|
+
// use getElement() with the default "body" to get a fresh Element on each instantiation
|
|
138
|
+
config.rootElement = index.getElement(config.rootElement);
|
|
139
|
+
return config;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
_append() {
|
|
143
|
+
if (this._isAppended) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const element = this._getElement();
|
|
148
|
+
|
|
149
|
+
this._config.rootElement.append(element);
|
|
150
|
+
|
|
151
|
+
EventHandler__default.default.on(element, EVENT_MOUSEDOWN, () => {
|
|
152
|
+
index.execute(this._config.clickCallback);
|
|
153
|
+
});
|
|
154
|
+
this._isAppended = true;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
_emulateAnimation(callback) {
|
|
158
|
+
index.executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return Backdrop;
|
|
164
|
+
|
|
165
|
+
}));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Bootstrap component-functions.js v5.2.2 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('../dom/event-handler'), require('./index')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['exports', '../dom/event-handler', './index'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComponentFunctions = {}, global.EventHandler, global.Index));
|
|
10
|
+
})(this, (function (exports, EventHandler, index) { 'use strict';
|
|
11
|
+
|
|
12
|
+
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
|
+
|
|
14
|
+
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* --------------------------------------------------------------------------
|
|
18
|
+
* Bootstrap (v5.2.2): util/component-functions.js
|
|
19
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
20
|
+
* --------------------------------------------------------------------------
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const enableDismissTrigger = (component, method = 'hide') => {
|
|
24
|
+
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
|
25
|
+
const name = component.NAME;
|
|
26
|
+
EventHandler__default.default.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
|
27
|
+
if (['A', 'AREA'].includes(this.tagName)) {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (index.isDisabled(this)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const target = index.getElementFromSelector(this) || this.closest(`.${name}`);
|
|
36
|
+
const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
|
37
|
+
|
|
38
|
+
instance[method]();
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.enableDismissTrigger = enableDismissTrigger;
|
|
43
|
+
|
|
44
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
45
|
+
|
|
46
|
+
}));
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Bootstrap config.js v5.2.2 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./index'), require('../dom/manipulator')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['./index', '../dom/manipulator'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Config = factory(global.Index, global.Manipulator));
|
|
10
|
+
})(this, (function (index, Manipulator) { 'use strict';
|
|
11
|
+
|
|
12
|
+
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
|
+
|
|
14
|
+
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* --------------------------------------------------------------------------
|
|
18
|
+
* Bootstrap (v5.2.2): util/config.js
|
|
19
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
20
|
+
* --------------------------------------------------------------------------
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Class definition
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
class Config {
|
|
27
|
+
// Getters
|
|
28
|
+
static get Default() {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static get DefaultType() {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static get NAME() {
|
|
37
|
+
throw new Error('You have to implement the static method "NAME", for each component!');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_getConfig(config) {
|
|
41
|
+
config = this._mergeConfigObj(config);
|
|
42
|
+
config = this._configAfterMerge(config);
|
|
43
|
+
|
|
44
|
+
this._typeCheckConfig(config);
|
|
45
|
+
|
|
46
|
+
return config;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
_configAfterMerge(config) {
|
|
50
|
+
return config;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_mergeConfigObj(config, element) {
|
|
54
|
+
const jsonConfig = index.isElement(element) ? Manipulator__default.default.getDataAttribute(element, 'config') : {}; // try to parse
|
|
55
|
+
|
|
56
|
+
return { ...this.constructor.Default,
|
|
57
|
+
...(typeof jsonConfig === 'object' ? jsonConfig : {}),
|
|
58
|
+
...(index.isElement(element) ? Manipulator__default.default.getDataAttributes(element) : {}),
|
|
59
|
+
...(typeof config === 'object' ? config : {})
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
|
|
64
|
+
for (const property of Object.keys(configTypes)) {
|
|
65
|
+
const expectedTypes = configTypes[property];
|
|
66
|
+
const value = config[property];
|
|
67
|
+
const valueType = index.isElement(value) ? 'element' : index.toType(value);
|
|
68
|
+
|
|
69
|
+
if (!new RegExp(expectedTypes).test(valueType)) {
|
|
70
|
+
throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return Config;
|
|
78
|
+
|
|
79
|
+
}));
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Bootstrap focustrap.js v5.2.2 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
*/
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler'), require('../dom/selector-engine'), require('./config')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['../dom/event-handler', '../dom/selector-engine', './config'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Focustrap = factory(global.EventHandler, global.SelectorEngine, global.Config));
|
|
10
|
+
})(this, (function (EventHandler, SelectorEngine, Config) { 'use strict';
|
|
11
|
+
|
|
12
|
+
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
|
+
|
|
14
|
+
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
+
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
|
16
|
+
const Config__default = /*#__PURE__*/_interopDefaultLegacy(Config);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* --------------------------------------------------------------------------
|
|
20
|
+
* Bootstrap (v5.2.2): util/focustrap.js
|
|
21
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
22
|
+
* --------------------------------------------------------------------------
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Constants
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const NAME = 'focustrap';
|
|
29
|
+
const DATA_KEY = 'bs.focustrap';
|
|
30
|
+
const EVENT_KEY = `.${DATA_KEY}`;
|
|
31
|
+
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
|
|
32
|
+
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`;
|
|
33
|
+
const TAB_KEY = 'Tab';
|
|
34
|
+
const TAB_NAV_FORWARD = 'forward';
|
|
35
|
+
const TAB_NAV_BACKWARD = 'backward';
|
|
36
|
+
const Default = {
|
|
37
|
+
autofocus: true,
|
|
38
|
+
trapElement: null // The element to trap focus inside of
|
|
39
|
+
|
|
40
|
+
};
|
|
41
|
+
const DefaultType = {
|
|
42
|
+
autofocus: 'boolean',
|
|
43
|
+
trapElement: 'element'
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Class definition
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
class FocusTrap extends Config__default.default {
|
|
50
|
+
constructor(config) {
|
|
51
|
+
super();
|
|
52
|
+
this._config = this._getConfig(config);
|
|
53
|
+
this._isActive = false;
|
|
54
|
+
this._lastTabNavDirection = null;
|
|
55
|
+
} // Getters
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
static get Default() {
|
|
59
|
+
return Default;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static get DefaultType() {
|
|
63
|
+
return DefaultType;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static get NAME() {
|
|
67
|
+
return NAME;
|
|
68
|
+
} // Public
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
activate() {
|
|
72
|
+
if (this._isActive) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (this._config.autofocus) {
|
|
77
|
+
this._config.trapElement.focus();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
EventHandler__default.default.off(document, EVENT_KEY); // guard against infinite focus loop
|
|
81
|
+
|
|
82
|
+
EventHandler__default.default.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
|
|
83
|
+
EventHandler__default.default.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
|
84
|
+
this._isActive = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
deactivate() {
|
|
88
|
+
if (!this._isActive) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this._isActive = false;
|
|
93
|
+
EventHandler__default.default.off(document, EVENT_KEY);
|
|
94
|
+
} // Private
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
_handleFocusin(event) {
|
|
98
|
+
const {
|
|
99
|
+
trapElement
|
|
100
|
+
} = this._config;
|
|
101
|
+
|
|
102
|
+
if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const elements = SelectorEngine__default.default.focusableChildren(trapElement);
|
|
107
|
+
|
|
108
|
+
if (elements.length === 0) {
|
|
109
|
+
trapElement.focus();
|
|
110
|
+
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
|
111
|
+
elements[elements.length - 1].focus();
|
|
112
|
+
} else {
|
|
113
|
+
elements[0].focus();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_handleKeydown(event) {
|
|
118
|
+
if (event.key !== TAB_KEY) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return FocusTrap;
|
|
128
|
+
|
|
129
|
+
}));
|