bootstrap 5.1.3 → 5.3.5
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/.github/workflows/ci.yml +61 -0
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/README.md +35 -14
- data/Rakefile +16 -5
- data/assets/javascripts/bootstrap/alert.js +22 -167
- data/assets/javascripts/bootstrap/base-component.js +34 -133
- data/assets/javascripts/bootstrap/button.js +19 -86
- data/assets/javascripts/bootstrap/carousel.js +209 -564
- data/assets/javascripts/bootstrap/collapse.js +78 -324
- data/assets/javascripts/bootstrap/dom/data.js +8 -14
- data/assets/javascripts/bootstrap/dom/event-handler.js +89 -174
- data/assets/javascripts/bootstrap/dom/manipulator.js +22 -39
- data/assets/javascripts/bootstrap/dom/selector-engine.js +47 -71
- data/assets/javascripts/bootstrap/dropdown.js +135 -420
- data/assets/javascripts/bootstrap/modal.js +115 -837
- data/assets/javascripts/bootstrap/offcanvas.js +93 -714
- data/assets/javascripts/bootstrap/popover.js +42 -130
- data/assets/javascripts/bootstrap/scrollspy.js +180 -296
- data/assets/javascripts/bootstrap/tab.js +197 -245
- data/assets/javascripts/bootstrap/toast.js +52 -276
- data/assets/javascripts/bootstrap/tooltip.js +283 -744
- data/assets/javascripts/bootstrap/util/backdrop.js +138 -0
- data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
- data/assets/javascripts/bootstrap/util/config.js +67 -0
- data/assets/javascripts/bootstrap/util/focustrap.js +112 -0
- data/assets/javascripts/bootstrap/util/index.js +280 -0
- data/assets/javascripts/bootstrap/util/sanitizer.js +113 -0
- data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
- data/assets/javascripts/bootstrap/util/swipe.js +134 -0
- data/assets/javascripts/bootstrap/util/template-factory.js +150 -0
- data/assets/javascripts/bootstrap-global-this-define.js +1 -1
- data/assets/javascripts/bootstrap-sprockets.js +15 -6
- data/assets/javascripts/bootstrap.js +2278 -2831
- data/assets/javascripts/bootstrap.min.js +3 -3
- data/assets/stylesheets/_bootstrap-grid.scss +4 -9
- data/assets/stylesheets/_bootstrap-reboot.scss +4 -7
- data/assets/stylesheets/_bootstrap-utilities.scss +19 -0
- data/assets/stylesheets/_bootstrap.scss +5 -6
- data/assets/stylesheets/bootstrap/_accordion.scss +68 -33
- data/assets/stylesheets/bootstrap/_alert.scss +25 -14
- data/assets/stylesheets/bootstrap/_badge.scss +14 -5
- data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
- data/assets/stylesheets/bootstrap/_button-group.scss +12 -4
- data/assets/stylesheets/bootstrap/_buttons.scss +133 -28
- data/assets/stylesheets/bootstrap/_card.scss +61 -39
- data/assets/stylesheets/bootstrap/_carousel.scss +22 -25
- data/assets/stylesheets/bootstrap/_close.scss +36 -10
- data/assets/stylesheets/bootstrap/_containers.scss +1 -1
- data/assets/stylesheets/bootstrap/_dropdown.scss +86 -76
- data/assets/stylesheets/bootstrap/_functions.scss +10 -10
- data/assets/stylesheets/bootstrap/_grid.scss +9 -3
- data/assets/stylesheets/bootstrap/_helpers.scss +3 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +81 -56
- data/assets/stylesheets/bootstrap/_maps.scss +174 -0
- data/assets/stylesheets/bootstrap/_mixins.scss +1 -2
- data/assets/stylesheets/bootstrap/_modal.scss +76 -45
- data/assets/stylesheets/bootstrap/_nav.scss +87 -29
- data/assets/stylesheets/bootstrap/_navbar.scss +102 -148
- data/assets/stylesheets/bootstrap/_offcanvas.scss +125 -61
- 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 +31 -11
- data/assets/stylesheets/bootstrap/_reboot.scss +32 -46
- data/assets/stylesheets/bootstrap/_root.scss +155 -22
- data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
- data/assets/stylesheets/bootstrap/_tables.scss +40 -24
- data/assets/stylesheets/bootstrap/_toasts.scss +38 -16
- data/assets/stylesheets/bootstrap/_tooltip.scss +60 -56
- data/assets/stylesheets/bootstrap/_type.scss +3 -1
- data/assets/stylesheets/bootstrap/_utilities.scss +209 -33
- data/assets/stylesheets/bootstrap/_variables-dark.scss +102 -0
- data/assets/stylesheets/bootstrap/_variables.scss +415 -303
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +39 -5
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +51 -14
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +36 -41
- data/assets/stylesheets/bootstrap/forms/_form-range.scss +3 -3
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +12 -4
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +20 -9
- data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +7 -0
- data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +20 -2
- data/assets/stylesheets/bootstrap/helpers/_focus-ring.scss +5 -0
- data/assets/stylesheets/bootstrap/helpers/_icon-link.scss +25 -0
- 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 +2 -2
- data/assets/stylesheets/bootstrap/mixins/_alert.scss +11 -4
- data/assets/stylesheets/bootstrap/mixins/_banner.scss +7 -0
- data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
- data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
- data/assets/stylesheets/bootstrap/mixins/_caret.scss +30 -25
- data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
- data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
- data/assets/stylesheets/bootstrap/mixins/_forms.scss +38 -19
- data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +15 -15
- data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -0
- 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 +14 -6
- data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +6 -2
- data/assets/stylesheets/bootstrap/vendor/_rfs.scss +23 -29
- data/bootstrap.gemspec +3 -3
- data/lib/bootstrap/engine.rb +17 -2
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +10 -5
- data/tasks/updater/network.rb +2 -2
- data/tasks/updater/scss.rb +2 -2
- data/tasks/updater.rb +2 -2
- data/test/dummy_rails/config/application.rb +0 -2
- data/test/dummy_rails/public/favicon.ico +0 -0
- data/test/gemfiles/rails_4_2.gemfile +2 -1
- data/test/gemfiles/rails_5_0.gemfile +1 -2
- data/test/gemfiles/rails_5_1.gemfile +1 -2
- data/test/gemfiles/rails_5_2.gemfile +7 -0
- data/test/gemfiles/rails_6_0.gemfile +1 -1
- data/test/gemfiles/rails_6_1.gemfile +1 -1
- data/test/gemfiles/rails_7_0_dartsass.gemfile +7 -0
- data/test/gemfiles/rails_7_0_sassc.gemfile +7 -0
- data/test/rails_test.rb +0 -5
- data/test/test_helper.rb +3 -2
- metadata +49 -29
- data/.travis.yml +0 -32
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +0 -18
|
@@ -1,622 +1,24 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Bootstrap modal.js v5.
|
|
3
|
-
* Copyright 2011-
|
|
2
|
+
* Bootstrap modal.js v5.3.5 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2025 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('./
|
|
8
|
-
typeof define === 'function' && define.amd ? define(['./
|
|
9
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.
|
|
10
|
-
})(this, (function (
|
|
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 Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
|
16
|
-
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
|
17
|
-
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* --------------------------------------------------------------------------
|
|
21
|
-
* Bootstrap (v5.1.3): util/index.js
|
|
22
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
23
|
-
* --------------------------------------------------------------------------
|
|
24
|
-
*/
|
|
25
|
-
const MILLISECONDS_MULTIPLIER = 1000;
|
|
26
|
-
const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
|
27
|
-
|
|
28
|
-
const toType = obj => {
|
|
29
|
-
if (obj === null || obj === undefined) {
|
|
30
|
-
return `${obj}`;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const getSelector = element => {
|
|
37
|
-
let selector = element.getAttribute('data-bs-target');
|
|
38
|
-
|
|
39
|
-
if (!selector || selector === '#') {
|
|
40
|
-
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
|
41
|
-
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
|
42
|
-
// `document.querySelector` will rightfully complain it is invalid.
|
|
43
|
-
// See https://github.com/twbs/bootstrap/issues/32273
|
|
44
|
-
|
|
45
|
-
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
|
46
|
-
return null;
|
|
47
|
-
} // Just in case some CMS puts out a full URL with the anchor appended
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
|
51
|
-
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return selector;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const getElementFromSelector = element => {
|
|
61
|
-
const selector = getSelector(element);
|
|
62
|
-
return selector ? document.querySelector(selector) : null;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const getTransitionDurationFromElement = element => {
|
|
66
|
-
if (!element) {
|
|
67
|
-
return 0;
|
|
68
|
-
} // Get transition-duration of the element
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
let {
|
|
72
|
-
transitionDuration,
|
|
73
|
-
transitionDelay
|
|
74
|
-
} = window.getComputedStyle(element);
|
|
75
|
-
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
|
76
|
-
const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
|
|
77
|
-
|
|
78
|
-
if (!floatTransitionDuration && !floatTransitionDelay) {
|
|
79
|
-
return 0;
|
|
80
|
-
} // If multiple durations are defined, take the first
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
transitionDuration = transitionDuration.split(',')[0];
|
|
84
|
-
transitionDelay = transitionDelay.split(',')[0];
|
|
85
|
-
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const triggerTransitionEnd = element => {
|
|
89
|
-
element.dispatchEvent(new Event(TRANSITION_END));
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const isElement = obj => {
|
|
93
|
-
if (!obj || typeof obj !== 'object') {
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (typeof obj.jquery !== 'undefined') {
|
|
98
|
-
obj = obj[0];
|
|
99
|
-
}
|
|
100
|
-
|
|
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;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (typeof obj === 'string' && obj.length > 0) {
|
|
111
|
-
return document.querySelector(obj);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return null;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const typeCheckConfig = (componentName, config, configTypes) => {
|
|
118
|
-
Object.keys(configTypes).forEach(property => {
|
|
119
|
-
const expectedTypes = configTypes[property];
|
|
120
|
-
const value = config[property];
|
|
121
|
-
const valueType = value && isElement(value) ? 'element' : toType(value);
|
|
122
|
-
|
|
123
|
-
if (!new RegExp(expectedTypes).test(valueType)) {
|
|
124
|
-
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
const isVisible = element => {
|
|
130
|
-
if (!isElement(element) || element.getClientRects().length === 0) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
|
|
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;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (typeof element.disabled !== 'undefined') {
|
|
147
|
-
return element.disabled;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
const reflow = element => {
|
|
163
|
-
// eslint-disable-next-line no-unused-expressions
|
|
164
|
-
element.offsetHeight;
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
const getjQuery = () => {
|
|
168
|
-
const {
|
|
169
|
-
jQuery
|
|
170
|
-
} = window;
|
|
171
|
-
|
|
172
|
-
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
|
173
|
-
return jQuery;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return null;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
const DOMContentLoadedCallbacks = [];
|
|
180
|
-
|
|
181
|
-
const onDOMContentLoaded = callback => {
|
|
182
|
-
if (document.readyState === 'loading') {
|
|
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);
|
|
191
|
-
} else {
|
|
192
|
-
callback();
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const isRTL = () => document.documentElement.dir === 'rtl';
|
|
197
|
-
|
|
198
|
-
const defineJQueryPlugin = plugin => {
|
|
199
|
-
onDOMContentLoaded(() => {
|
|
200
|
-
const $ = getjQuery();
|
|
201
|
-
/* istanbul ignore if */
|
|
202
|
-
|
|
203
|
-
if ($) {
|
|
204
|
-
const name = plugin.NAME;
|
|
205
|
-
const JQUERY_NO_CONFLICT = $.fn[name];
|
|
206
|
-
$.fn[name] = plugin.jQueryInterface;
|
|
207
|
-
$.fn[name].Constructor = plugin;
|
|
208
|
-
|
|
209
|
-
$.fn[name].noConflict = () => {
|
|
210
|
-
$.fn[name] = JQUERY_NO_CONFLICT;
|
|
211
|
-
return plugin.jQueryInterface;
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
const execute = callback => {
|
|
218
|
-
if (typeof callback === 'function') {
|
|
219
|
-
callback();
|
|
220
|
-
}
|
|
221
|
-
};
|
|
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
|
-
|
|
253
|
-
/**
|
|
254
|
-
* --------------------------------------------------------------------------
|
|
255
|
-
* Bootstrap (v5.1.3): util/scrollBar.js
|
|
256
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
257
|
-
* --------------------------------------------------------------------------
|
|
258
|
-
*/
|
|
259
|
-
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
|
260
|
-
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
|
261
|
-
|
|
262
|
-
class ScrollBarHelper {
|
|
263
|
-
constructor() {
|
|
264
|
-
this._element = document.body;
|
|
265
|
-
}
|
|
266
|
-
|
|
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
|
-
}
|
|
272
|
-
|
|
273
|
-
hide() {
|
|
274
|
-
const width = this.getWidth();
|
|
275
|
-
|
|
276
|
-
this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
|
|
277
|
-
|
|
278
|
-
|
|
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
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
|
|
283
|
-
|
|
284
|
-
this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
_disableOverFlow() {
|
|
288
|
-
this._saveInitialAttribute(this._element, 'overflow');
|
|
289
|
-
|
|
290
|
-
this._element.style.overflow = 'hidden';
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
_setElementAttributes(selector, styleProp, callback) {
|
|
294
|
-
const scrollbarWidth = this.getWidth();
|
|
295
|
-
|
|
296
|
-
const manipulationCallBack = element => {
|
|
297
|
-
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
this._saveInitialAttribute(element, styleProp);
|
|
302
|
-
|
|
303
|
-
const calculatedValue = window.getComputedStyle(element)[styleProp];
|
|
304
|
-
element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
this._applyManipulationCallback(selector, manipulationCallBack);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
reset() {
|
|
311
|
-
this._resetElementAttributes(this._element, 'overflow');
|
|
312
|
-
|
|
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
|
-
};
|
|
339
|
-
|
|
340
|
-
this._applyManipulationCallback(selector, manipulationCallBack);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
_applyManipulationCallback(selector, callBack) {
|
|
344
|
-
if (isElement(selector)) {
|
|
345
|
-
callBack(selector);
|
|
346
|
-
} else {
|
|
347
|
-
SelectorEngine__default.default.find(selector, this._element).forEach(callBack);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
isOverflowing() {
|
|
352
|
-
return this.getWidth() > 0;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
}
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./base-component.js'), require('./dom/event-handler.js'), require('./dom/selector-engine.js'), require('./util/backdrop.js'), require('./util/component-functions.js'), require('./util/focustrap.js'), require('./util/index.js'), require('./util/scrollbar.js')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/backdrop', './util/component-functions', './util/focustrap', './util/index', './util/scrollbar'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Modal = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Backdrop, global.ComponentFunctions, global.Focustrap, global.Index, global.Scrollbar));
|
|
10
|
+
})(this, (function (BaseComponent, EventHandler, SelectorEngine, Backdrop, componentFunctions_js, FocusTrap, index_js, ScrollBarHelper) { 'use strict';
|
|
356
11
|
|
|
357
12
|
/**
|
|
358
13
|
* --------------------------------------------------------------------------
|
|
359
|
-
* Bootstrap
|
|
14
|
+
* Bootstrap modal.js
|
|
360
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
361
16
|
* --------------------------------------------------------------------------
|
|
362
17
|
*/
|
|
363
|
-
const Default$2 = {
|
|
364
|
-
className: 'modal-backdrop',
|
|
365
|
-
isVisible: true,
|
|
366
|
-
// if false, we use the backdrop helper without adding any element to the dom
|
|
367
|
-
isAnimated: false,
|
|
368
|
-
rootElement: 'body',
|
|
369
|
-
// give the choice to place backdrop under different elements
|
|
370
|
-
clickCallback: null
|
|
371
|
-
};
|
|
372
|
-
const DefaultType$2 = {
|
|
373
|
-
className: 'string',
|
|
374
|
-
isVisible: 'boolean',
|
|
375
|
-
isAnimated: 'boolean',
|
|
376
|
-
rootElement: '(element|string)',
|
|
377
|
-
clickCallback: '(function|null)'
|
|
378
|
-
};
|
|
379
|
-
const NAME$2 = 'backdrop';
|
|
380
|
-
const CLASS_NAME_FADE$1 = 'fade';
|
|
381
|
-
const CLASS_NAME_SHOW$1 = 'show';
|
|
382
|
-
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
|
|
383
18
|
|
|
384
|
-
class Backdrop {
|
|
385
|
-
constructor(config) {
|
|
386
|
-
this._config = this._getConfig(config);
|
|
387
|
-
this._isAppended = false;
|
|
388
|
-
this._element = null;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
show(callback) {
|
|
392
|
-
if (!this._config.isVisible) {
|
|
393
|
-
execute(callback);
|
|
394
|
-
return;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
this._append();
|
|
398
|
-
|
|
399
|
-
if (this._config.isAnimated) {
|
|
400
|
-
reflow(this._getElement());
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
this._getElement().classList.add(CLASS_NAME_SHOW$1);
|
|
404
|
-
|
|
405
|
-
this._emulateAnimation(() => {
|
|
406
|
-
execute(callback);
|
|
407
|
-
});
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
hide(callback) {
|
|
411
|
-
if (!this._config.isVisible) {
|
|
412
|
-
execute(callback);
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
this._getElement().classList.remove(CLASS_NAME_SHOW$1);
|
|
417
|
-
|
|
418
|
-
this._emulateAnimation(() => {
|
|
419
|
-
this.dispose();
|
|
420
|
-
execute(callback);
|
|
421
|
-
});
|
|
422
|
-
} // Private
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
_getElement() {
|
|
426
|
-
if (!this._element) {
|
|
427
|
-
const backdrop = document.createElement('div');
|
|
428
|
-
backdrop.className = this._config.className;
|
|
429
|
-
|
|
430
|
-
if (this._config.isAnimated) {
|
|
431
|
-
backdrop.classList.add(CLASS_NAME_FADE$1);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
this._element = backdrop;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
return this._element;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
_getConfig(config) {
|
|
441
|
-
config = { ...Default$2,
|
|
442
|
-
...(typeof config === 'object' ? config : {})
|
|
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);
|
|
447
|
-
return config;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
_append() {
|
|
451
|
-
if (this._isAppended) {
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
this._config.rootElement.append(this._getElement());
|
|
456
|
-
|
|
457
|
-
EventHandler__default.default.on(this._getElement(), EVENT_MOUSEDOWN, () => {
|
|
458
|
-
execute(this._config.clickCallback);
|
|
459
|
-
});
|
|
460
|
-
this._isAppended = true;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
dispose() {
|
|
464
|
-
if (!this._isAppended) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
EventHandler__default.default.off(this._element, EVENT_MOUSEDOWN);
|
|
469
|
-
|
|
470
|
-
this._element.remove();
|
|
471
|
-
|
|
472
|
-
this._isAppended = false;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
_emulateAnimation(callback) {
|
|
476
|
-
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
}
|
|
480
19
|
|
|
481
20
|
/**
|
|
482
|
-
* --------------------------------------------------------------------------
|
|
483
|
-
* Bootstrap (v5.1.3): 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) {
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
|
|
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;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* --------------------------------------------------------------------------
|
|
586
|
-
* Bootstrap (v5.1.3): 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.3): modal.js
|
|
613
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
614
|
-
* --------------------------------------------------------------------------
|
|
615
|
-
*/
|
|
616
|
-
/**
|
|
617
|
-
* ------------------------------------------------------------------------
|
|
618
21
|
* Constants
|
|
619
|
-
* ------------------------------------------------------------------------
|
|
620
22
|
*/
|
|
621
23
|
|
|
622
24
|
const NAME = 'modal';
|
|
@@ -624,16 +26,6 @@
|
|
|
624
26
|
const EVENT_KEY = `.${DATA_KEY}`;
|
|
625
27
|
const DATA_API_KEY = '.data-api';
|
|
626
28
|
const ESCAPE_KEY = 'Escape';
|
|
627
|
-
const Default = {
|
|
628
|
-
backdrop: true,
|
|
629
|
-
keyboard: true,
|
|
630
|
-
focus: true
|
|
631
|
-
};
|
|
632
|
-
const DefaultType = {
|
|
633
|
-
backdrop: '(boolean|string)',
|
|
634
|
-
keyboard: 'boolean',
|
|
635
|
-
focus: 'boolean'
|
|
636
|
-
};
|
|
637
29
|
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
|
638
30
|
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`;
|
|
639
31
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
|
@@ -641,9 +33,8 @@
|
|
|
641
33
|
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
|
642
34
|
const EVENT_RESIZE = `resize${EVENT_KEY}`;
|
|
643
35
|
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
|
|
644
|
-
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
|
645
|
-
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`;
|
|
646
36
|
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`;
|
|
37
|
+
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
|
|
647
38
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
|
|
648
39
|
const CLASS_NAME_OPEN = 'modal-open';
|
|
649
40
|
const CLASS_NAME_FADE = 'fade';
|
|
@@ -653,388 +44,275 @@
|
|
|
653
44
|
const SELECTOR_DIALOG = '.modal-dialog';
|
|
654
45
|
const SELECTOR_MODAL_BODY = '.modal-body';
|
|
655
46
|
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]';
|
|
47
|
+
const Default = {
|
|
48
|
+
backdrop: true,
|
|
49
|
+
focus: true,
|
|
50
|
+
keyboard: true
|
|
51
|
+
};
|
|
52
|
+
const DefaultType = {
|
|
53
|
+
backdrop: '(boolean|string)',
|
|
54
|
+
focus: 'boolean',
|
|
55
|
+
keyboard: 'boolean'
|
|
56
|
+
};
|
|
57
|
+
|
|
656
58
|
/**
|
|
657
|
-
*
|
|
658
|
-
* Class Definition
|
|
659
|
-
* ------------------------------------------------------------------------
|
|
59
|
+
* Class definition
|
|
660
60
|
*/
|
|
661
61
|
|
|
662
|
-
class Modal extends
|
|
62
|
+
class Modal extends BaseComponent {
|
|
663
63
|
constructor(element, config) {
|
|
664
|
-
super(element);
|
|
665
|
-
this.
|
|
666
|
-
this._dialog = SelectorEngine__default.default.findOne(SELECTOR_DIALOG, this._element);
|
|
64
|
+
super(element, config);
|
|
65
|
+
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
|
|
667
66
|
this._backdrop = this._initializeBackDrop();
|
|
668
67
|
this._focustrap = this._initializeFocusTrap();
|
|
669
68
|
this._isShown = false;
|
|
670
|
-
this._ignoreBackdropClick = false;
|
|
671
69
|
this._isTransitioning = false;
|
|
672
70
|
this._scrollBar = new ScrollBarHelper();
|
|
673
|
-
|
|
674
|
-
|
|
71
|
+
this._addEventListeners();
|
|
72
|
+
}
|
|
675
73
|
|
|
74
|
+
// Getters
|
|
676
75
|
static get Default() {
|
|
677
76
|
return Default;
|
|
678
77
|
}
|
|
679
|
-
|
|
78
|
+
static get DefaultType() {
|
|
79
|
+
return DefaultType;
|
|
80
|
+
}
|
|
680
81
|
static get NAME() {
|
|
681
82
|
return NAME;
|
|
682
|
-
}
|
|
683
|
-
|
|
83
|
+
}
|
|
684
84
|
|
|
85
|
+
// Public
|
|
685
86
|
toggle(relatedTarget) {
|
|
686
87
|
return this._isShown ? this.hide() : this.show(relatedTarget);
|
|
687
88
|
}
|
|
688
|
-
|
|
689
89
|
show(relatedTarget) {
|
|
690
90
|
if (this._isShown || this._isTransitioning) {
|
|
691
91
|
return;
|
|
692
92
|
}
|
|
693
|
-
|
|
694
|
-
const showEvent = EventHandler__default.default.trigger(this._element, EVENT_SHOW, {
|
|
93
|
+
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
|
|
695
94
|
relatedTarget
|
|
696
95
|
});
|
|
697
|
-
|
|
698
96
|
if (showEvent.defaultPrevented) {
|
|
699
97
|
return;
|
|
700
98
|
}
|
|
701
|
-
|
|
702
99
|
this._isShown = true;
|
|
703
|
-
|
|
704
|
-
if (this._isAnimated()) {
|
|
705
|
-
this._isTransitioning = true;
|
|
706
|
-
}
|
|
707
|
-
|
|
100
|
+
this._isTransitioning = true;
|
|
708
101
|
this._scrollBar.hide();
|
|
709
|
-
|
|
710
102
|
document.body.classList.add(CLASS_NAME_OPEN);
|
|
711
|
-
|
|
712
103
|
this._adjustDialog();
|
|
713
|
-
|
|
714
|
-
this._setEscapeEvent();
|
|
715
|
-
|
|
716
|
-
this._setResizeEvent();
|
|
717
|
-
|
|
718
|
-
EventHandler__default.default.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
|
|
719
|
-
EventHandler__default.default.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
|
|
720
|
-
if (event.target === this._element) {
|
|
721
|
-
this._ignoreBackdropClick = true;
|
|
722
|
-
}
|
|
723
|
-
});
|
|
724
|
-
});
|
|
725
|
-
|
|
726
|
-
this._showBackdrop(() => this._showElement(relatedTarget));
|
|
104
|
+
this._backdrop.show(() => this._showElement(relatedTarget));
|
|
727
105
|
}
|
|
728
|
-
|
|
729
106
|
hide() {
|
|
730
107
|
if (!this._isShown || this._isTransitioning) {
|
|
731
108
|
return;
|
|
732
109
|
}
|
|
733
|
-
|
|
734
|
-
const hideEvent = EventHandler__default.default.trigger(this._element, EVENT_HIDE);
|
|
735
|
-
|
|
110
|
+
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
|
736
111
|
if (hideEvent.defaultPrevented) {
|
|
737
112
|
return;
|
|
738
113
|
}
|
|
739
|
-
|
|
740
114
|
this._isShown = false;
|
|
741
|
-
|
|
742
|
-
const isAnimated = this._isAnimated();
|
|
743
|
-
|
|
744
|
-
if (isAnimated) {
|
|
745
|
-
this._isTransitioning = true;
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
this._setEscapeEvent();
|
|
749
|
-
|
|
750
|
-
this._setResizeEvent();
|
|
751
|
-
|
|
115
|
+
this._isTransitioning = true;
|
|
752
116
|
this._focustrap.deactivate();
|
|
753
|
-
|
|
754
117
|
this._element.classList.remove(CLASS_NAME_SHOW);
|
|
755
|
-
|
|
756
|
-
EventHandler__default.default.off(this._element, EVENT_CLICK_DISMISS);
|
|
757
|
-
EventHandler__default.default.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);
|
|
758
|
-
|
|
759
|
-
this._queueCallback(() => this._hideModal(), this._element, isAnimated);
|
|
118
|
+
this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
|
|
760
119
|
}
|
|
761
|
-
|
|
762
120
|
dispose() {
|
|
763
|
-
|
|
764
|
-
|
|
121
|
+
EventHandler.off(window, EVENT_KEY);
|
|
122
|
+
EventHandler.off(this._dialog, EVENT_KEY);
|
|
765
123
|
this._backdrop.dispose();
|
|
766
|
-
|
|
767
124
|
this._focustrap.deactivate();
|
|
768
|
-
|
|
769
125
|
super.dispose();
|
|
770
126
|
}
|
|
771
|
-
|
|
772
127
|
handleUpdate() {
|
|
773
128
|
this._adjustDialog();
|
|
774
|
-
}
|
|
775
|
-
|
|
129
|
+
}
|
|
776
130
|
|
|
131
|
+
// Private
|
|
777
132
|
_initializeBackDrop() {
|
|
778
133
|
return new Backdrop({
|
|
779
134
|
isVisible: Boolean(this._config.backdrop),
|
|
780
|
-
// 'static' option will be translated to true, and booleans will keep their value
|
|
135
|
+
// 'static' option will be translated to true, and booleans will keep their value,
|
|
781
136
|
isAnimated: this._isAnimated()
|
|
782
137
|
});
|
|
783
138
|
}
|
|
784
|
-
|
|
785
139
|
_initializeFocusTrap() {
|
|
786
140
|
return new FocusTrap({
|
|
787
141
|
trapElement: this._element
|
|
788
142
|
});
|
|
789
143
|
}
|
|
790
|
-
|
|
791
|
-
_getConfig(config) {
|
|
792
|
-
config = { ...Default,
|
|
793
|
-
...Manipulator__default.default.getDataAttributes(this._element),
|
|
794
|
-
...(typeof config === 'object' ? config : {})
|
|
795
|
-
};
|
|
796
|
-
typeCheckConfig(NAME, config, DefaultType);
|
|
797
|
-
return config;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
144
|
_showElement(relatedTarget) {
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
const modalBody = SelectorEngine__default.default.findOne(SELECTOR_MODAL_BODY, this._dialog);
|
|
804
|
-
|
|
805
|
-
if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
|
|
806
|
-
// Don't move modal's DOM position
|
|
145
|
+
// try to append dynamic modal
|
|
146
|
+
if (!document.body.contains(this._element)) {
|
|
807
147
|
document.body.append(this._element);
|
|
808
148
|
}
|
|
809
|
-
|
|
810
149
|
this._element.style.display = 'block';
|
|
811
|
-
|
|
812
150
|
this._element.removeAttribute('aria-hidden');
|
|
813
|
-
|
|
814
151
|
this._element.setAttribute('aria-modal', true);
|
|
815
|
-
|
|
816
152
|
this._element.setAttribute('role', 'dialog');
|
|
817
|
-
|
|
818
153
|
this._element.scrollTop = 0;
|
|
819
|
-
|
|
154
|
+
const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
|
|
820
155
|
if (modalBody) {
|
|
821
156
|
modalBody.scrollTop = 0;
|
|
822
157
|
}
|
|
823
|
-
|
|
824
|
-
if (isAnimated) {
|
|
825
|
-
reflow(this._element);
|
|
826
|
-
}
|
|
827
|
-
|
|
158
|
+
index_js.reflow(this._element);
|
|
828
159
|
this._element.classList.add(CLASS_NAME_SHOW);
|
|
829
|
-
|
|
830
160
|
const transitionComplete = () => {
|
|
831
161
|
if (this._config.focus) {
|
|
832
162
|
this._focustrap.activate();
|
|
833
163
|
}
|
|
834
|
-
|
|
835
164
|
this._isTransitioning = false;
|
|
836
|
-
|
|
165
|
+
EventHandler.trigger(this._element, EVENT_SHOWN, {
|
|
837
166
|
relatedTarget
|
|
838
167
|
});
|
|
839
168
|
};
|
|
840
|
-
|
|
841
|
-
this._queueCallback(transitionComplete, this._dialog, isAnimated);
|
|
169
|
+
this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
|
|
842
170
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
171
|
+
_addEventListeners() {
|
|
172
|
+
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
|
173
|
+
if (event.key !== ESCAPE_KEY) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (this._config.keyboard) {
|
|
177
|
+
this.hide();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this._triggerBackdropTransition();
|
|
181
|
+
});
|
|
182
|
+
EventHandler.on(window, EVENT_RESIZE, () => {
|
|
183
|
+
if (this._isShown && !this._isTransitioning) {
|
|
184
|
+
this._adjustDialog();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
|
|
188
|
+
// a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
|
|
189
|
+
EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
|
|
190
|
+
if (this._element !== event.target || this._element !== event2.target) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (this._config.backdrop === 'static') {
|
|
851
194
|
this._triggerBackdropTransition();
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (this._config.backdrop) {
|
|
198
|
+
this.hide();
|
|
852
199
|
}
|
|
853
200
|
});
|
|
854
|
-
}
|
|
855
|
-
EventHandler__default.default.off(this._element, EVENT_KEYDOWN_DISMISS);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
_setResizeEvent() {
|
|
860
|
-
if (this._isShown) {
|
|
861
|
-
EventHandler__default.default.on(window, EVENT_RESIZE, () => this._adjustDialog());
|
|
862
|
-
} else {
|
|
863
|
-
EventHandler__default.default.off(window, EVENT_RESIZE);
|
|
864
|
-
}
|
|
201
|
+
});
|
|
865
202
|
}
|
|
866
|
-
|
|
867
203
|
_hideModal() {
|
|
868
204
|
this._element.style.display = 'none';
|
|
869
|
-
|
|
870
205
|
this._element.setAttribute('aria-hidden', true);
|
|
871
|
-
|
|
872
206
|
this._element.removeAttribute('aria-modal');
|
|
873
|
-
|
|
874
207
|
this._element.removeAttribute('role');
|
|
875
|
-
|
|
876
208
|
this._isTransitioning = false;
|
|
877
|
-
|
|
878
209
|
this._backdrop.hide(() => {
|
|
879
210
|
document.body.classList.remove(CLASS_NAME_OPEN);
|
|
880
|
-
|
|
881
211
|
this._resetAdjustments();
|
|
882
|
-
|
|
883
212
|
this._scrollBar.reset();
|
|
884
|
-
|
|
885
|
-
EventHandler__default.default.trigger(this._element, EVENT_HIDDEN);
|
|
886
|
-
});
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
_showBackdrop(callback) {
|
|
890
|
-
EventHandler__default.default.on(this._element, EVENT_CLICK_DISMISS, event => {
|
|
891
|
-
if (this._ignoreBackdropClick) {
|
|
892
|
-
this._ignoreBackdropClick = false;
|
|
893
|
-
return;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
if (event.target !== event.currentTarget) {
|
|
897
|
-
return;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
if (this._config.backdrop === true) {
|
|
901
|
-
this.hide();
|
|
902
|
-
} else if (this._config.backdrop === 'static') {
|
|
903
|
-
this._triggerBackdropTransition();
|
|
904
|
-
}
|
|
213
|
+
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
|
905
214
|
});
|
|
906
|
-
|
|
907
|
-
this._backdrop.show(callback);
|
|
908
215
|
}
|
|
909
|
-
|
|
910
216
|
_isAnimated() {
|
|
911
217
|
return this._element.classList.contains(CLASS_NAME_FADE);
|
|
912
218
|
}
|
|
913
|
-
|
|
914
219
|
_triggerBackdropTransition() {
|
|
915
|
-
const hideEvent =
|
|
916
|
-
|
|
220
|
+
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
|
917
221
|
if (hideEvent.defaultPrevented) {
|
|
918
222
|
return;
|
|
919
223
|
}
|
|
920
|
-
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
|
|
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)) {
|
|
224
|
+
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
|
225
|
+
const initialOverflowY = this._element.style.overflowY;
|
|
226
|
+
// return if the following background transition hasn't yet completed
|
|
227
|
+
if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
|
|
929
228
|
return;
|
|
930
229
|
}
|
|
931
|
-
|
|
932
230
|
if (!isModalOverflowing) {
|
|
933
|
-
style.overflowY = 'hidden';
|
|
231
|
+
this._element.style.overflowY = 'hidden';
|
|
934
232
|
}
|
|
935
|
-
|
|
936
|
-
classList.add(CLASS_NAME_STATIC);
|
|
937
|
-
|
|
233
|
+
this._element.classList.add(CLASS_NAME_STATIC);
|
|
938
234
|
this._queueCallback(() => {
|
|
939
|
-
classList.remove(CLASS_NAME_STATIC);
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
style.overflowY = '';
|
|
944
|
-
}, this._dialog);
|
|
945
|
-
}
|
|
235
|
+
this._element.classList.remove(CLASS_NAME_STATIC);
|
|
236
|
+
this._queueCallback(() => {
|
|
237
|
+
this._element.style.overflowY = initialOverflowY;
|
|
238
|
+
}, this._dialog);
|
|
946
239
|
}, this._dialog);
|
|
947
|
-
|
|
948
240
|
this._element.focus();
|
|
949
|
-
}
|
|
950
|
-
// the following methods are used to handle overflowing modals
|
|
951
|
-
// ----------------------------------------------------------------------
|
|
241
|
+
}
|
|
952
242
|
|
|
243
|
+
/**
|
|
244
|
+
* The following methods are used to handle overflowing modals
|
|
245
|
+
*/
|
|
953
246
|
|
|
954
247
|
_adjustDialog() {
|
|
955
248
|
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
|
956
|
-
|
|
957
249
|
const scrollbarWidth = this._scrollBar.getWidth();
|
|
958
|
-
|
|
959
250
|
const isBodyOverflowing = scrollbarWidth > 0;
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
this._element.style
|
|
251
|
+
if (isBodyOverflowing && !isModalOverflowing) {
|
|
252
|
+
const property = index_js.isRTL() ? 'paddingLeft' : 'paddingRight';
|
|
253
|
+
this._element.style[property] = `${scrollbarWidth}px`;
|
|
963
254
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
this._element.style
|
|
255
|
+
if (!isBodyOverflowing && isModalOverflowing) {
|
|
256
|
+
const property = index_js.isRTL() ? 'paddingRight' : 'paddingLeft';
|
|
257
|
+
this._element.style[property] = `${scrollbarWidth}px`;
|
|
967
258
|
}
|
|
968
259
|
}
|
|
969
|
-
|
|
970
260
|
_resetAdjustments() {
|
|
971
261
|
this._element.style.paddingLeft = '';
|
|
972
262
|
this._element.style.paddingRight = '';
|
|
973
|
-
}
|
|
974
|
-
|
|
263
|
+
}
|
|
975
264
|
|
|
265
|
+
// Static
|
|
976
266
|
static jQueryInterface(config, relatedTarget) {
|
|
977
267
|
return this.each(function () {
|
|
978
268
|
const data = Modal.getOrCreateInstance(this, config);
|
|
979
|
-
|
|
980
269
|
if (typeof config !== 'string') {
|
|
981
270
|
return;
|
|
982
271
|
}
|
|
983
|
-
|
|
984
272
|
if (typeof data[config] === 'undefined') {
|
|
985
273
|
throw new TypeError(`No method named "${config}"`);
|
|
986
274
|
}
|
|
987
|
-
|
|
988
275
|
data[config](relatedTarget);
|
|
989
276
|
});
|
|
990
277
|
}
|
|
991
|
-
|
|
992
278
|
}
|
|
279
|
+
|
|
993
280
|
/**
|
|
994
|
-
*
|
|
995
|
-
* Data Api implementation
|
|
996
|
-
* ------------------------------------------------------------------------
|
|
281
|
+
* Data API implementation
|
|
997
282
|
*/
|
|
998
283
|
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
const target = getElementFromSelector(this);
|
|
1002
|
-
|
|
284
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
|
285
|
+
const target = SelectorEngine.getElementFromSelector(this);
|
|
1003
286
|
if (['A', 'AREA'].includes(this.tagName)) {
|
|
1004
287
|
event.preventDefault();
|
|
1005
288
|
}
|
|
1006
|
-
|
|
1007
|
-
EventHandler__default.default.one(target, EVENT_SHOW, showEvent => {
|
|
289
|
+
EventHandler.one(target, EVENT_SHOW, showEvent => {
|
|
1008
290
|
if (showEvent.defaultPrevented) {
|
|
1009
291
|
// only register focus restorer if modal will actually get shown
|
|
1010
292
|
return;
|
|
1011
293
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
if (isVisible(this)) {
|
|
294
|
+
EventHandler.one(target, EVENT_HIDDEN, () => {
|
|
295
|
+
if (index_js.isVisible(this)) {
|
|
1015
296
|
this.focus();
|
|
1016
297
|
}
|
|
1017
298
|
});
|
|
1018
|
-
});
|
|
1019
|
-
|
|
1020
|
-
const allReadyOpen = SelectorEngine__default.default.findOne(OPEN_SELECTOR);
|
|
299
|
+
});
|
|
1021
300
|
|
|
1022
|
-
|
|
1023
|
-
|
|
301
|
+
// avoid conflict when clicking modal toggler while another one is open
|
|
302
|
+
const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
|
|
303
|
+
if (alreadyOpen) {
|
|
304
|
+
Modal.getInstance(alreadyOpen).hide();
|
|
1024
305
|
}
|
|
1025
|
-
|
|
1026
306
|
const data = Modal.getOrCreateInstance(target);
|
|
1027
307
|
data.toggle(this);
|
|
1028
308
|
});
|
|
1029
|
-
enableDismissTrigger(Modal);
|
|
309
|
+
componentFunctions_js.enableDismissTrigger(Modal);
|
|
310
|
+
|
|
1030
311
|
/**
|
|
1031
|
-
* ------------------------------------------------------------------------
|
|
1032
312
|
* jQuery
|
|
1033
|
-
* ------------------------------------------------------------------------
|
|
1034
|
-
* add .Modal to jQuery only if jQuery is present
|
|
1035
313
|
*/
|
|
1036
314
|
|
|
1037
|
-
defineJQueryPlugin(Modal);
|
|
315
|
+
index_js.defineJQueryPlugin(Modal);
|
|
1038
316
|
|
|
1039
317
|
return Modal;
|
|
1040
318
|
|