bootstrap 5.2.3 → 5.3.0.alpha3
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 +1 -1
- data/assets/javascripts/bootstrap/alert.js +21 -32
- data/assets/javascripts/bootstrap/base-component.js +21 -38
- data/assets/javascripts/bootstrap/button.js +18 -22
- data/assets/javascripts/bootstrap/carousel.js +51 -135
- data/assets/javascripts/bootstrap/collapse.js +39 -102
- data/assets/javascripts/bootstrap/dom/data.js +8 -12
- data/assets/javascripts/bootstrap/dom/event-handler.js +18 -66
- data/assets/javascripts/bootstrap/dom/manipulator.js +4 -17
- data/assets/javascripts/bootstrap/dom/selector-engine.js +41 -24
- data/assets/javascripts/bootstrap/dropdown.js +73 -145
- data/assets/javascripts/bootstrap/modal.js +52 -133
- data/assets/javascripts/bootstrap/offcanvas.js +49 -102
- data/assets/javascripts/bootstrap/popover.js +22 -29
- data/assets/javascripts/bootstrap/scrollspy.js +51 -89
- data/assets/javascripts/bootstrap/tab.js +51 -109
- data/assets/javascripts/bootstrap/toast.js +30 -73
- data/assets/javascripts/bootstrap/tooltip.js +74 -177
- data/assets/javascripts/bootstrap/util/backdrop.js +27 -54
- data/assets/javascripts/bootstrap/util/component-functions.js +13 -19
- data/assets/javascripts/bootstrap/util/config.js +14 -27
- data/assets/javascripts/bootstrap/util/focustrap.js +19 -36
- data/assets/javascripts/bootstrap/util/index.js +42 -111
- data/assets/javascripts/bootstrap/util/sanitizer.js +13 -19
- data/assets/javascripts/bootstrap/util/scrollbar.js +23 -50
- data/assets/javascripts/bootstrap/util/swipe.js +26 -48
- data/assets/javascripts/bootstrap/util/template-factory.js +24 -52
- data/assets/javascripts/bootstrap-sprockets.js +1 -1
- data/assets/javascripts/bootstrap.js +626 -1406
- data/assets/javascripts/bootstrap.min.js +3 -3
- data/assets/stylesheets/_bootstrap-grid.scss +1 -3
- data/assets/stylesheets/_bootstrap-reboot.scss +1 -0
- data/assets/stylesheets/_bootstrap.scss +1 -0
- data/assets/stylesheets/bootstrap/_accordion.scss +9 -0
- data/assets/stylesheets/bootstrap/_alert.scss +8 -11
- data/assets/stylesheets/bootstrap/_button-group.scss +2 -2
- data/assets/stylesheets/bootstrap/_buttons.scss +3 -3
- data/assets/stylesheets/bootstrap/_card.scss +5 -0
- data/assets/stylesheets/bootstrap/_carousel.scss +20 -2
- data/assets/stylesheets/bootstrap/_close.scss +32 -9
- data/assets/stylesheets/bootstrap/_dropdown.scss +1 -0
- data/assets/stylesheets/bootstrap/_functions.scss +1 -1
- data/assets/stylesheets/bootstrap/_grid.scss +6 -0
- data/assets/stylesheets/bootstrap/_helpers.scss +2 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +12 -7
- data/assets/stylesheets/bootstrap/_maps.scss +120 -0
- data/assets/stylesheets/bootstrap/_mixins.scss +1 -2
- data/assets/stylesheets/bootstrap/_nav.scss +40 -3
- data/assets/stylesheets/bootstrap/_navbar.scss +13 -3
- data/assets/stylesheets/bootstrap/_offcanvas.scss +4 -2
- data/assets/stylesheets/bootstrap/_pagination.scss +1 -1
- data/assets/stylesheets/bootstrap/_progress.scss +10 -1
- data/assets/stylesheets/bootstrap/_reboot.scss +3 -3
- data/assets/stylesheets/bootstrap/_root.scss +125 -10
- data/assets/stylesheets/bootstrap/_tables.scss +1 -1
- data/assets/stylesheets/bootstrap/_tooltip.scss +4 -5
- data/assets/stylesheets/bootstrap/_utilities.scss +172 -13
- data/assets/stylesheets/bootstrap/_variables-dark.scss +85 -0
- data/assets/stylesheets/bootstrap/_variables.scss +260 -151
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +1 -0
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +21 -3
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +24 -11
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +23 -3
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +11 -2
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +1 -1
- data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +22 -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/mixins/_alert.scss +4 -1
- data/assets/stylesheets/bootstrap/mixins/_banner.scss +2 -4
- data/assets/stylesheets/bootstrap/mixins/_caret.scss +30 -25
- data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
- data/assets/stylesheets/bootstrap/mixins/_forms.scss +8 -7
- data/assets/stylesheets/bootstrap/mixins/_list-group.scss +2 -0
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +5 -1
- data/assets/stylesheets/bootstrap/vendor/_rfs.scss +23 -29
- data/bootstrap.gemspec +1 -1
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +1 -1
- data/tasks/updater/scss.rb +1 -1
- metadata +10 -6
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap index.js v5.
|
3
|
-
* Copyright 2011-
|
2
|
+
* Bootstrap index.js v5.3.0-alpha3 (https://getbootstrap.com/)
|
3
|
+
* Copyright 2011-2023 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) {
|
@@ -11,193 +11,146 @@
|
|
11
11
|
|
12
12
|
/**
|
13
13
|
* --------------------------------------------------------------------------
|
14
|
-
* Bootstrap
|
14
|
+
* Bootstrap util/index.js
|
15
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
16
16
|
* --------------------------------------------------------------------------
|
17
17
|
*/
|
18
|
+
|
18
19
|
const MAX_UID = 1000000;
|
19
20
|
const MILLISECONDS_MULTIPLIER = 1000;
|
20
|
-
const TRANSITION_END = 'transitionend';
|
21
|
+
const TRANSITION_END = 'transitionend';
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Properly escape IDs selectors to handle weird IDs
|
25
|
+
* @param {string} selector
|
26
|
+
* @returns {string}
|
27
|
+
*/
|
28
|
+
const parseSelector = selector => {
|
29
|
+
if (selector && window.CSS && window.CSS.escape) {
|
30
|
+
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
31
|
+
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
32
|
+
}
|
33
|
+
return selector;
|
34
|
+
};
|
21
35
|
|
36
|
+
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
22
37
|
const toType = object => {
|
23
38
|
if (object === null || object === undefined) {
|
24
39
|
return `${object}`;
|
25
40
|
}
|
26
|
-
|
27
41
|
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
28
42
|
};
|
43
|
+
|
29
44
|
/**
|
30
45
|
* Public Util API
|
31
46
|
*/
|
32
47
|
|
33
|
-
|
34
48
|
const getUID = prefix => {
|
35
49
|
do {
|
36
50
|
prefix += Math.floor(Math.random() * MAX_UID);
|
37
51
|
} while (document.getElementById(prefix));
|
38
|
-
|
39
52
|
return prefix;
|
40
53
|
};
|
41
|
-
|
42
|
-
const getSelector = element => {
|
43
|
-
let selector = element.getAttribute('data-bs-target');
|
44
|
-
|
45
|
-
if (!selector || selector === '#') {
|
46
|
-
let hrefAttribute = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
47
|
-
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
48
|
-
// `document.querySelector` will rightfully complain it is invalid.
|
49
|
-
// See https://github.com/twbs/bootstrap/issues/32273
|
50
|
-
|
51
|
-
if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
|
52
|
-
return null;
|
53
|
-
} // Just in case some CMS puts out a full URL with the anchor appended
|
54
|
-
|
55
|
-
|
56
|
-
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
|
57
|
-
hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
|
58
|
-
}
|
59
|
-
|
60
|
-
selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
|
61
|
-
}
|
62
|
-
|
63
|
-
return selector;
|
64
|
-
};
|
65
|
-
|
66
|
-
const getSelectorFromElement = element => {
|
67
|
-
const selector = getSelector(element);
|
68
|
-
|
69
|
-
if (selector) {
|
70
|
-
return document.querySelector(selector) ? selector : null;
|
71
|
-
}
|
72
|
-
|
73
|
-
return null;
|
74
|
-
};
|
75
|
-
|
76
|
-
const getElementFromSelector = element => {
|
77
|
-
const selector = getSelector(element);
|
78
|
-
return selector ? document.querySelector(selector) : null;
|
79
|
-
};
|
80
|
-
|
81
54
|
const getTransitionDurationFromElement = element => {
|
82
55
|
if (!element) {
|
83
56
|
return 0;
|
84
|
-
}
|
85
|
-
|
57
|
+
}
|
86
58
|
|
59
|
+
// Get transition-duration of the element
|
87
60
|
let {
|
88
61
|
transitionDuration,
|
89
62
|
transitionDelay
|
90
63
|
} = window.getComputedStyle(element);
|
91
64
|
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
92
|
-
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
65
|
+
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
93
66
|
|
67
|
+
// Return 0 if element or transition duration is not found
|
94
68
|
if (!floatTransitionDuration && !floatTransitionDelay) {
|
95
69
|
return 0;
|
96
|
-
}
|
97
|
-
|
70
|
+
}
|
98
71
|
|
72
|
+
// If multiple durations are defined, take the first
|
99
73
|
transitionDuration = transitionDuration.split(',')[0];
|
100
74
|
transitionDelay = transitionDelay.split(',')[0];
|
101
75
|
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
102
76
|
};
|
103
|
-
|
104
77
|
const triggerTransitionEnd = element => {
|
105
78
|
element.dispatchEvent(new Event(TRANSITION_END));
|
106
79
|
};
|
107
|
-
|
108
80
|
const isElement = object => {
|
109
81
|
if (!object || typeof object !== 'object') {
|
110
82
|
return false;
|
111
83
|
}
|
112
|
-
|
113
84
|
if (typeof object.jquery !== 'undefined') {
|
114
85
|
object = object[0];
|
115
86
|
}
|
116
|
-
|
117
87
|
return typeof object.nodeType !== 'undefined';
|
118
88
|
};
|
119
|
-
|
120
89
|
const getElement = object => {
|
121
90
|
// it's a jQuery object or a node element
|
122
91
|
if (isElement(object)) {
|
123
92
|
return object.jquery ? object[0] : object;
|
124
93
|
}
|
125
|
-
|
126
94
|
if (typeof object === 'string' && object.length > 0) {
|
127
|
-
return document.querySelector(object);
|
95
|
+
return document.querySelector(parseSelector(object));
|
128
96
|
}
|
129
|
-
|
130
97
|
return null;
|
131
98
|
};
|
132
|
-
|
133
99
|
const isVisible = element => {
|
134
100
|
if (!isElement(element) || element.getClientRects().length === 0) {
|
135
101
|
return false;
|
136
102
|
}
|
137
|
-
|
138
|
-
|
139
|
-
|
103
|
+
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
104
|
+
// Handle `details` element as its content may falsie appear visible when it is closed
|
140
105
|
const closedDetails = element.closest('details:not([open])');
|
141
|
-
|
142
106
|
if (!closedDetails) {
|
143
107
|
return elementIsVisible;
|
144
108
|
}
|
145
|
-
|
146
109
|
if (closedDetails !== element) {
|
147
110
|
const summary = element.closest('summary');
|
148
|
-
|
149
111
|
if (summary && summary.parentNode !== closedDetails) {
|
150
112
|
return false;
|
151
113
|
}
|
152
|
-
|
153
114
|
if (summary === null) {
|
154
115
|
return false;
|
155
116
|
}
|
156
117
|
}
|
157
|
-
|
158
118
|
return elementIsVisible;
|
159
119
|
};
|
160
|
-
|
161
120
|
const isDisabled = element => {
|
162
121
|
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
163
122
|
return true;
|
164
123
|
}
|
165
|
-
|
166
124
|
if (element.classList.contains('disabled')) {
|
167
125
|
return true;
|
168
126
|
}
|
169
|
-
|
170
127
|
if (typeof element.disabled !== 'undefined') {
|
171
128
|
return element.disabled;
|
172
129
|
}
|
173
|
-
|
174
130
|
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
175
131
|
};
|
176
|
-
|
177
132
|
const findShadowRoot = element => {
|
178
133
|
if (!document.documentElement.attachShadow) {
|
179
134
|
return null;
|
180
|
-
}
|
181
|
-
|
135
|
+
}
|
182
136
|
|
137
|
+
// Can find the shadow root otherwise it'll return the document
|
183
138
|
if (typeof element.getRootNode === 'function') {
|
184
139
|
const root = element.getRootNode();
|
185
140
|
return root instanceof ShadowRoot ? root : null;
|
186
141
|
}
|
187
|
-
|
188
142
|
if (element instanceof ShadowRoot) {
|
189
143
|
return element;
|
190
|
-
}
|
191
|
-
|
144
|
+
}
|
192
145
|
|
146
|
+
// when we don't find a shadow root
|
193
147
|
if (!element.parentNode) {
|
194
148
|
return null;
|
195
149
|
}
|
196
|
-
|
197
150
|
return findShadowRoot(element.parentNode);
|
198
151
|
};
|
199
|
-
|
200
152
|
const noop = () => {};
|
153
|
+
|
201
154
|
/**
|
202
155
|
* Trick to restart an element's animation
|
203
156
|
*
|
@@ -206,8 +159,6 @@
|
|
206
159
|
*
|
207
160
|
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
208
161
|
*/
|
209
|
-
|
210
|
-
|
211
162
|
const reflow = element => {
|
212
163
|
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
213
164
|
};
|
@@ -216,12 +167,9 @@
|
|
216
167
|
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
217
168
|
return window.jQuery;
|
218
169
|
}
|
219
|
-
|
220
170
|
return null;
|
221
171
|
};
|
222
|
-
|
223
172
|
const DOMContentLoadedCallbacks = [];
|
224
|
-
|
225
173
|
const onDOMContentLoaded = callback => {
|
226
174
|
if (document.readyState === 'loading') {
|
227
175
|
// add listener on the first call when the document is in loading state
|
@@ -232,26 +180,21 @@
|
|
232
180
|
}
|
233
181
|
});
|
234
182
|
}
|
235
|
-
|
236
183
|
DOMContentLoadedCallbacks.push(callback);
|
237
184
|
} else {
|
238
185
|
callback();
|
239
186
|
}
|
240
187
|
};
|
241
|
-
|
242
188
|
const isRTL = () => document.documentElement.dir === 'rtl';
|
243
|
-
|
244
189
|
const defineJQueryPlugin = plugin => {
|
245
190
|
onDOMContentLoaded(() => {
|
246
191
|
const $ = getjQuery();
|
247
192
|
/* istanbul ignore if */
|
248
|
-
|
249
193
|
if ($) {
|
250
194
|
const name = plugin.NAME;
|
251
195
|
const JQUERY_NO_CONFLICT = $.fn[name];
|
252
196
|
$.fn[name] = plugin.jQueryInterface;
|
253
197
|
$.fn[name].Constructor = plugin;
|
254
|
-
|
255
198
|
$.fn[name].noConflict = () => {
|
256
199
|
$.fn[name] = JQUERY_NO_CONFLICT;
|
257
200
|
return plugin.jQueryInterface;
|
@@ -259,35 +202,27 @@
|
|
259
202
|
}
|
260
203
|
});
|
261
204
|
};
|
262
|
-
|
263
|
-
|
264
|
-
if (typeof callback === 'function') {
|
265
|
-
callback();
|
266
|
-
}
|
205
|
+
const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
|
206
|
+
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;
|
267
207
|
};
|
268
|
-
|
269
208
|
const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
|
270
209
|
if (!waitForTransition) {
|
271
210
|
execute(callback);
|
272
211
|
return;
|
273
212
|
}
|
274
|
-
|
275
213
|
const durationPadding = 5;
|
276
214
|
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
277
215
|
let called = false;
|
278
|
-
|
279
216
|
const handler = ({
|
280
217
|
target
|
281
218
|
}) => {
|
282
219
|
if (target !== transitionElement) {
|
283
220
|
return;
|
284
221
|
}
|
285
|
-
|
286
222
|
called = true;
|
287
223
|
transitionElement.removeEventListener(TRANSITION_END, handler);
|
288
224
|
execute(callback);
|
289
225
|
};
|
290
|
-
|
291
226
|
transitionElement.addEventListener(TRANSITION_END, handler);
|
292
227
|
setTimeout(() => {
|
293
228
|
if (!called) {
|
@@ -295,6 +230,7 @@
|
|
295
230
|
}
|
296
231
|
}, emulatedDuration);
|
297
232
|
};
|
233
|
+
|
298
234
|
/**
|
299
235
|
* Return the previous/next element of a list.
|
300
236
|
*
|
@@ -304,23 +240,19 @@
|
|
304
240
|
* @param isCycleAllowed
|
305
241
|
* @return {Element|elem} The proper element
|
306
242
|
*/
|
307
|
-
|
308
|
-
|
309
243
|
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
310
244
|
const listLength = list.length;
|
311
|
-
let index = list.indexOf(activeElement);
|
312
|
-
// depending on the direction and if cycle is allowed
|
245
|
+
let index = list.indexOf(activeElement);
|
313
246
|
|
247
|
+
// if the element does not exist in the list return an element
|
248
|
+
// depending on the direction and if cycle is allowed
|
314
249
|
if (index === -1) {
|
315
250
|
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
316
251
|
}
|
317
|
-
|
318
252
|
index += shouldGetNext ? 1 : -1;
|
319
|
-
|
320
253
|
if (isCycleAllowed) {
|
321
254
|
index = (index + listLength) % listLength;
|
322
255
|
}
|
323
|
-
|
324
256
|
return list[Math.max(0, Math.min(index, listLength - 1))];
|
325
257
|
};
|
326
258
|
|
@@ -329,9 +261,7 @@
|
|
329
261
|
exports.executeAfterTransition = executeAfterTransition;
|
330
262
|
exports.findShadowRoot = findShadowRoot;
|
331
263
|
exports.getElement = getElement;
|
332
|
-
exports.getElementFromSelector = getElementFromSelector;
|
333
264
|
exports.getNextActiveElement = getNextActiveElement;
|
334
|
-
exports.getSelectorFromElement = getSelectorFromElement;
|
335
265
|
exports.getTransitionDurationFromElement = getTransitionDurationFromElement;
|
336
266
|
exports.getUID = getUID;
|
337
267
|
exports.getjQuery = getjQuery;
|
@@ -341,10 +271,11 @@
|
|
341
271
|
exports.isVisible = isVisible;
|
342
272
|
exports.noop = noop;
|
343
273
|
exports.onDOMContentLoaded = onDOMContentLoaded;
|
274
|
+
exports.parseSelector = parseSelector;
|
344
275
|
exports.reflow = reflow;
|
345
276
|
exports.toType = toType;
|
346
277
|
exports.triggerTransitionEnd = triggerTransitionEnd;
|
347
278
|
|
348
|
-
Object.
|
279
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
349
280
|
|
350
281
|
}));
|
@@ -1,6 +1,6 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap sanitizer.js v5.
|
3
|
-
* Copyright 2011-
|
2
|
+
* Bootstrap sanitizer.js v5.3.0-alpha3 (https://getbootstrap.com/)
|
3
|
+
* Copyright 2011-2023 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) {
|
@@ -11,42 +11,41 @@
|
|
11
11
|
|
12
12
|
/**
|
13
13
|
* --------------------------------------------------------------------------
|
14
|
-
* Bootstrap
|
14
|
+
* Bootstrap util/sanitizer.js
|
15
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
16
16
|
* --------------------------------------------------------------------------
|
17
17
|
*/
|
18
|
+
|
18
19
|
const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
|
19
|
-
|
20
|
+
|
20
21
|
/**
|
21
22
|
* A pattern that recognizes a commonly useful subset of URLs that are safe.
|
22
23
|
*
|
23
24
|
* Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
|
24
25
|
*/
|
25
|
-
|
26
26
|
const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
|
27
|
+
|
27
28
|
/**
|
28
29
|
* A pattern that matches safe data URLs. Only matches image, video and audio types.
|
29
30
|
*
|
30
31
|
* Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
|
31
32
|
*/
|
32
|
-
|
33
33
|
const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
|
34
|
-
|
35
34
|
const allowedAttribute = (attribute, allowedAttributeList) => {
|
36
35
|
const attributeName = attribute.nodeName.toLowerCase();
|
37
|
-
|
38
36
|
if (allowedAttributeList.includes(attributeName)) {
|
39
37
|
if (uriAttributes.has(attributeName)) {
|
40
38
|
return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));
|
41
39
|
}
|
42
|
-
|
43
40
|
return true;
|
44
|
-
}
|
45
|
-
|
41
|
+
}
|
46
42
|
|
43
|
+
// Check if a regular expression validates the attribute.
|
47
44
|
return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));
|
48
45
|
};
|
49
46
|
|
47
|
+
// js-docs-start allow-list
|
48
|
+
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
|
50
49
|
const DefaultAllowlist = {
|
51
50
|
// Global attributes allowed on any supplied element below.
|
52
51
|
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
|
@@ -80,43 +79,38 @@
|
|
80
79
|
u: [],
|
81
80
|
ul: []
|
82
81
|
};
|
82
|
+
// js-docs-end allow-list
|
83
|
+
|
83
84
|
function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
|
84
85
|
if (!unsafeHtml.length) {
|
85
86
|
return unsafeHtml;
|
86
87
|
}
|
87
|
-
|
88
88
|
if (sanitizeFunction && typeof sanitizeFunction === 'function') {
|
89
89
|
return sanitizeFunction(unsafeHtml);
|
90
90
|
}
|
91
|
-
|
92
91
|
const domParser = new window.DOMParser();
|
93
92
|
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
|
94
93
|
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
|
95
|
-
|
96
94
|
for (const element of elements) {
|
97
95
|
const elementName = element.nodeName.toLowerCase();
|
98
|
-
|
99
96
|
if (!Object.keys(allowList).includes(elementName)) {
|
100
97
|
element.remove();
|
101
98
|
continue;
|
102
99
|
}
|
103
|
-
|
104
100
|
const attributeList = [].concat(...element.attributes);
|
105
101
|
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
|
106
|
-
|
107
102
|
for (const attribute of attributeList) {
|
108
103
|
if (!allowedAttribute(attribute, allowedAttributes)) {
|
109
104
|
element.removeAttribute(attribute.nodeName);
|
110
105
|
}
|
111
106
|
}
|
112
107
|
}
|
113
|
-
|
114
108
|
return createdDocument.body.innerHTML;
|
115
109
|
}
|
116
110
|
|
117
111
|
exports.DefaultAllowlist = DefaultAllowlist;
|
118
112
|
exports.sanitizeHtml = sanitizeHtml;
|
119
113
|
|
120
|
-
Object.
|
114
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
121
115
|
|
122
116
|
}));
|
@@ -1,25 +1,21 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap scrollbar.js v5.
|
3
|
-
* Copyright 2011-
|
2
|
+
* Bootstrap scrollbar.js v5.3.0-alpha3 (https://getbootstrap.com/)
|
3
|
+
* Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4
4
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5
5
|
*/
|
6
6
|
(function (global, factory) {
|
7
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/
|
8
|
-
typeof define === 'function' && define.amd ? define(['../dom/
|
9
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollbar = factory(global.
|
10
|
-
})(this, (function (
|
11
|
-
|
12
|
-
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
13
|
-
|
14
|
-
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
15
|
-
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/manipulator.js'), require('../dom/selector-engine.js'), require('./index.js')) :
|
8
|
+
typeof define === 'function' && define.amd ? define(['../dom/manipulator', '../dom/selector-engine', './index'], factory) :
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollbar = factory(global.Manipulator, global.SelectorEngine, global.Index));
|
10
|
+
})(this, (function (Manipulator, SelectorEngine, index_js) { 'use strict';
|
16
11
|
|
17
12
|
/**
|
18
13
|
* --------------------------------------------------------------------------
|
19
|
-
* Bootstrap
|
14
|
+
* Bootstrap util/scrollBar.js
|
20
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
21
16
|
* --------------------------------------------------------------------------
|
22
17
|
*/
|
18
|
+
|
23
19
|
/**
|
24
20
|
* Constants
|
25
21
|
*/
|
@@ -28,6 +24,7 @@
|
|
28
24
|
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
29
25
|
const PROPERTY_PADDING = 'padding-right';
|
30
26
|
const PROPERTY_MARGIN = 'margin-right';
|
27
|
+
|
31
28
|
/**
|
32
29
|
* Class definition
|
33
30
|
*/
|
@@ -35,102 +32,78 @@
|
|
35
32
|
class ScrollBarHelper {
|
36
33
|
constructor() {
|
37
34
|
this._element = document.body;
|
38
|
-
}
|
39
|
-
|
35
|
+
}
|
40
36
|
|
37
|
+
// Public
|
41
38
|
getWidth() {
|
42
39
|
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
43
40
|
const documentWidth = document.documentElement.clientWidth;
|
44
41
|
return Math.abs(window.innerWidth - documentWidth);
|
45
42
|
}
|
46
|
-
|
47
43
|
hide() {
|
48
44
|
const width = this.getWidth();
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
54
|
-
|
55
|
-
|
45
|
+
this._disableOverFlow();
|
46
|
+
// give padding to element to balance the hidden scrollbar width
|
47
|
+
this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
48
|
+
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
56
49
|
this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
57
|
-
|
58
50
|
this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
|
59
51
|
}
|
60
|
-
|
61
52
|
reset() {
|
62
53
|
this._resetElementAttributes(this._element, 'overflow');
|
63
|
-
|
64
54
|
this._resetElementAttributes(this._element, PROPERTY_PADDING);
|
65
|
-
|
66
55
|
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
|
67
|
-
|
68
56
|
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
|
69
57
|
}
|
70
|
-
|
71
58
|
isOverflowing() {
|
72
59
|
return this.getWidth() > 0;
|
73
|
-
}
|
74
|
-
|
60
|
+
}
|
75
61
|
|
62
|
+
// Private
|
76
63
|
_disableOverFlow() {
|
77
64
|
this._saveInitialAttribute(this._element, 'overflow');
|
78
|
-
|
79
65
|
this._element.style.overflow = 'hidden';
|
80
66
|
}
|
81
|
-
|
82
67
|
_setElementAttributes(selector, styleProperty, callback) {
|
83
68
|
const scrollbarWidth = this.getWidth();
|
84
|
-
|
85
69
|
const manipulationCallBack = element => {
|
86
70
|
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
87
71
|
return;
|
88
72
|
}
|
89
|
-
|
90
73
|
this._saveInitialAttribute(element, styleProperty);
|
91
|
-
|
92
74
|
const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
|
93
75
|
element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
|
94
76
|
};
|
95
|
-
|
96
77
|
this._applyManipulationCallback(selector, manipulationCallBack);
|
97
78
|
}
|
98
|
-
|
99
79
|
_saveInitialAttribute(element, styleProperty) {
|
100
80
|
const actualValue = element.style.getPropertyValue(styleProperty);
|
101
|
-
|
102
81
|
if (actualValue) {
|
103
|
-
|
82
|
+
Manipulator.setDataAttribute(element, styleProperty, actualValue);
|
104
83
|
}
|
105
84
|
}
|
106
|
-
|
107
85
|
_resetElementAttributes(selector, styleProperty) {
|
108
86
|
const manipulationCallBack = element => {
|
109
|
-
const value =
|
110
|
-
|
87
|
+
const value = Manipulator.getDataAttribute(element, styleProperty);
|
88
|
+
// We only want to remove the property if the value is `null`; the value can also be zero
|
111
89
|
if (value === null) {
|
112
90
|
element.style.removeProperty(styleProperty);
|
113
91
|
return;
|
114
92
|
}
|
115
|
-
|
116
|
-
Manipulator__default.default.removeDataAttribute(element, styleProperty);
|
93
|
+
Manipulator.removeDataAttribute(element, styleProperty);
|
117
94
|
element.style.setProperty(styleProperty, value);
|
118
95
|
};
|
119
|
-
|
120
96
|
this._applyManipulationCallback(selector, manipulationCallBack);
|
121
97
|
}
|
122
|
-
|
123
98
|
_applyManipulationCallback(selector, callBack) {
|
124
|
-
if (
|
99
|
+
if (index_js.isElement(selector)) {
|
125
100
|
callBack(selector);
|
126
101
|
return;
|
127
102
|
}
|
128
|
-
|
129
|
-
for (const sel of SelectorEngine__default.default.find(selector, this._element)) {
|
103
|
+
for (const sel of SelectorEngine.find(selector, this._element)) {
|
130
104
|
callBack(sel);
|
131
105
|
}
|
132
106
|
}
|
133
|
-
|
134
107
|
}
|
135
108
|
|
136
109
|
return ScrollBarHelper;
|