bootstrap 5.2.3 → 5.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +11 -5
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -0
- data/README.md +8 -2
- data/Rakefile +17 -4
- data/assets/javascripts/bootstrap/alert.js +22 -32
- data/assets/javascripts/bootstrap/base-component.js +22 -38
- data/assets/javascripts/bootstrap/button.js +19 -22
- data/assets/javascripts/bootstrap/carousel.js +52 -135
- data/assets/javascripts/bootstrap/collapse.js +40 -102
- data/assets/javascripts/bootstrap/dom/data.js +8 -12
- data/assets/javascripts/bootstrap/dom/event-handler.js +19 -66
- data/assets/javascripts/bootstrap/dom/manipulator.js +4 -17
- data/assets/javascripts/bootstrap/dom/selector-engine.js +42 -24
- data/assets/javascripts/bootstrap/dropdown.js +74 -145
- data/assets/javascripts/bootstrap/modal.js +53 -133
- data/assets/javascripts/bootstrap/offcanvas.js +50 -102
- data/assets/javascripts/bootstrap/popover.js +23 -29
- data/assets/javascripts/bootstrap/scrollspy.js +53 -90
- data/assets/javascripts/bootstrap/tab.js +63 -112
- data/assets/javascripts/bootstrap/toast.js +31 -73
- data/assets/javascripts/bootstrap/tooltip.js +75 -177
- data/assets/javascripts/bootstrap/util/backdrop.js +27 -54
- data/assets/javascripts/bootstrap/util/component-functions.js +13 -18
- data/assets/javascripts/bootstrap/util/config.js +15 -27
- data/assets/javascripts/bootstrap/util/focustrap.js +19 -36
- data/assets/javascripts/bootstrap/util/index.js +42 -112
- data/assets/javascripts/bootstrap/util/sanitizer.js +33 -42
- data/assets/javascripts/bootstrap/util/scrollbar.js +24 -50
- data/assets/javascripts/bootstrap/util/swipe.js +27 -48
- data/assets/javascripts/bootstrap/util/template-factory.js +25 -52
- data/assets/javascripts/bootstrap-sprockets.js +9 -9
- data/assets/javascripts/bootstrap.js +692 -1447
- 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-utilities.scss +19 -0
- data/assets/stylesheets/_bootstrap.scss +1 -0
- data/assets/stylesheets/bootstrap/_accordion.scss +20 -11
- data/assets/stylesheets/bootstrap/_alert.scss +8 -11
- data/assets/stylesheets/bootstrap/_button-group.scss +2 -2
- data/assets/stylesheets/bootstrap/_buttons.scss +12 -3
- data/assets/stylesheets/bootstrap/_card.scss +5 -0
- data/assets/stylesheets/bootstrap/_carousel.scss +22 -12
- 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/_modal.scss +0 -1
- data/assets/stylesheets/bootstrap/_nav.scss +42 -17
- data/assets/stylesheets/bootstrap/_navbar.scss +15 -4
- data/assets/stylesheets/bootstrap/_offcanvas.scss +5 -6
- data/assets/stylesheets/bootstrap/_pagination.scss +1 -1
- data/assets/stylesheets/bootstrap/_progress.scss +10 -1
- data/assets/stylesheets/bootstrap/_reboot.scss +8 -7
- data/assets/stylesheets/bootstrap/_root.scss +124 -10
- data/assets/stylesheets/bootstrap/_tables.scss +19 -12
- data/assets/stylesheets/bootstrap/_tooltip.scss +4 -5
- data/assets/stylesheets/bootstrap/_utilities.scss +175 -16
- data/assets/stylesheets/bootstrap/_variables-dark.scss +87 -0
- data/assets/stylesheets/bootstrap/_variables.scss +289 -172
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +23 -3
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +27 -13
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +24 -4
- data/assets/stylesheets/bootstrap/forms/_form-range.scss +3 -3
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +12 -3
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +1 -1
- data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +1 -4
- 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/_vr.scss +1 -1
- 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 +20 -9
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +2 -2
- 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 +4 -3
- data/lib/bootstrap/engine.rb +17 -1
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +1 -1
- data/tasks/updater/scss.rb +2 -2
- data/test/gemfiles/rails_4_2.gemfile +2 -1
- data/test/gemfiles/rails_5_0.gemfile +1 -1
- data/test/gemfiles/rails_5_1.gemfile +1 -1
- data/test/gemfiles/rails_5_2.gemfile +1 -1
- data/test/gemfiles/rails_6_0.gemfile +1 -0
- data/test/gemfiles/rails_6_1.gemfile +1 -0
- data/test/gemfiles/rails_7_0_dartsass.gemfile +8 -0
- data/test/gemfiles/{rails_7_0.gemfile → rails_7_0_sassc.gemfile} +1 -0
- data/test/test_helper.rb +2 -2
- metadata +39 -19
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +0 -18
@@ -1,26 +1,22 @@
|
|
1
1
|
/*!
|
2
|
-
* Bootstrap scrollspy.js v5.
|
3
|
-
* Copyright 2011-
|
2
|
+
* Bootstrap scrollspy.js v5.3.3 (https://getbootstrap.com/)
|
3
|
+
* Copyright 2011-2024 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.Scrollspy = 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 SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
16
|
-
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
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/index.js')) :
|
8
|
+
typeof define === 'function' && define.amd ? define(['./base-component', './dom/event-handler', './dom/selector-engine', './util/index'], factory) :
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollspy = factory(global.BaseComponent, global.EventHandler, global.SelectorEngine, global.Index));
|
10
|
+
})(this, (function (BaseComponent, EventHandler, SelectorEngine, index_js) { 'use strict';
|
17
11
|
|
18
12
|
/**
|
19
13
|
* --------------------------------------------------------------------------
|
20
|
-
* Bootstrap
|
14
|
+
* Bootstrap scrollspy.js
|
21
15
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
22
16
|
* --------------------------------------------------------------------------
|
23
17
|
*/
|
18
|
+
|
19
|
+
|
24
20
|
/**
|
25
21
|
* Constants
|
26
22
|
*/
|
@@ -59,14 +55,16 @@
|
|
59
55
|
target: 'element',
|
60
56
|
threshold: 'array'
|
61
57
|
};
|
58
|
+
|
62
59
|
/**
|
63
60
|
* Class definition
|
64
61
|
*/
|
65
62
|
|
66
|
-
class ScrollSpy extends
|
63
|
+
class ScrollSpy extends BaseComponent {
|
67
64
|
constructor(element, config) {
|
68
|
-
super(element, config);
|
65
|
+
super(element, config);
|
69
66
|
|
67
|
+
// this._element is the observablesContainer and config.target the menu links wrapper
|
70
68
|
this._targetLinks = new Map();
|
71
69
|
this._observableSections = new Map();
|
72
70
|
this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
|
@@ -77,87 +75,75 @@
|
|
77
75
|
parentScrollTop: 0
|
78
76
|
};
|
79
77
|
this.refresh(); // initialize
|
80
|
-
}
|
81
|
-
|
78
|
+
}
|
82
79
|
|
80
|
+
// Getters
|
83
81
|
static get Default() {
|
84
82
|
return Default;
|
85
83
|
}
|
86
|
-
|
87
84
|
static get DefaultType() {
|
88
85
|
return DefaultType;
|
89
86
|
}
|
90
|
-
|
91
87
|
static get NAME() {
|
92
88
|
return NAME;
|
93
|
-
}
|
94
|
-
|
89
|
+
}
|
95
90
|
|
91
|
+
// Public
|
96
92
|
refresh() {
|
97
93
|
this._initializeTargetsAndObservables();
|
98
|
-
|
99
94
|
this._maybeEnableSmoothScroll();
|
100
|
-
|
101
95
|
if (this._observer) {
|
102
96
|
this._observer.disconnect();
|
103
97
|
} else {
|
104
98
|
this._observer = this._getNewObserver();
|
105
99
|
}
|
106
|
-
|
107
100
|
for (const section of this._observableSections.values()) {
|
108
101
|
this._observer.observe(section);
|
109
102
|
}
|
110
103
|
}
|
111
|
-
|
112
104
|
dispose() {
|
113
105
|
this._observer.disconnect();
|
114
|
-
|
115
106
|
super.dispose();
|
116
|
-
}
|
117
|
-
|
107
|
+
}
|
118
108
|
|
109
|
+
// Private
|
119
110
|
_configAfterMerge(config) {
|
120
111
|
// TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
|
121
|
-
config.target =
|
112
|
+
config.target = index_js.getElement(config.target) || document.body;
|
122
113
|
|
114
|
+
// TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
|
123
115
|
config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
|
124
|
-
|
125
116
|
if (typeof config.threshold === 'string') {
|
126
117
|
config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
|
127
118
|
}
|
128
|
-
|
129
119
|
return config;
|
130
120
|
}
|
131
|
-
|
132
121
|
_maybeEnableSmoothScroll() {
|
133
122
|
if (!this._config.smoothScroll) {
|
134
123
|
return;
|
135
|
-
}
|
136
|
-
|
124
|
+
}
|
137
125
|
|
138
|
-
|
139
|
-
|
126
|
+
// unregister any previous listeners
|
127
|
+
EventHandler.off(this._config.target, EVENT_CLICK);
|
128
|
+
EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
|
140
129
|
const observableSection = this._observableSections.get(event.target.hash);
|
141
|
-
|
142
130
|
if (observableSection) {
|
143
131
|
event.preventDefault();
|
144
132
|
const root = this._rootElement || window;
|
145
133
|
const height = observableSection.offsetTop - this._element.offsetTop;
|
146
|
-
|
147
134
|
if (root.scrollTo) {
|
148
135
|
root.scrollTo({
|
149
136
|
top: height,
|
150
137
|
behavior: 'smooth'
|
151
138
|
});
|
152
139
|
return;
|
153
|
-
}
|
154
|
-
|
140
|
+
}
|
155
141
|
|
142
|
+
// Chrome 60 doesn't support `scrollTo`
|
156
143
|
root.scrollTop = height;
|
157
144
|
}
|
158
145
|
});
|
159
146
|
}
|
160
|
-
|
161
147
|
_getNewObserver() {
|
162
148
|
const options = {
|
163
149
|
root: this._rootElement,
|
@@ -165,146 +151,123 @@
|
|
165
151
|
rootMargin: this._config.rootMargin
|
166
152
|
};
|
167
153
|
return new IntersectionObserver(entries => this._observerCallback(entries), options);
|
168
|
-
}
|
169
|
-
|
154
|
+
}
|
170
155
|
|
156
|
+
// The logic of selection
|
171
157
|
_observerCallback(entries) {
|
172
158
|
const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
|
173
|
-
|
174
159
|
const activate = entry => {
|
175
160
|
this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
|
176
|
-
|
177
161
|
this._process(targetElement(entry));
|
178
162
|
};
|
179
|
-
|
180
163
|
const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
|
181
164
|
const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
|
182
165
|
this._previousScrollData.parentScrollTop = parentScrollTop;
|
183
|
-
|
184
166
|
for (const entry of entries) {
|
185
167
|
if (!entry.isIntersecting) {
|
186
168
|
this._activeTarget = null;
|
187
|
-
|
188
169
|
this._clearActiveClass(targetElement(entry));
|
189
|
-
|
190
170
|
continue;
|
191
171
|
}
|
192
|
-
|
193
|
-
|
194
|
-
|
172
|
+
const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;
|
173
|
+
// if we are scrolling down, pick the bigger offsetTop
|
195
174
|
if (userScrollsDown && entryIsLowerThanPrevious) {
|
196
|
-
activate(entry);
|
197
|
-
|
175
|
+
activate(entry);
|
176
|
+
// if parent isn't scrolled, let's keep the first visible item, breaking the iteration
|
198
177
|
if (!parentScrollTop) {
|
199
178
|
return;
|
200
179
|
}
|
201
|
-
|
202
180
|
continue;
|
203
|
-
}
|
204
|
-
|
181
|
+
}
|
205
182
|
|
183
|
+
// if we are scrolling up, pick the smallest offsetTop
|
206
184
|
if (!userScrollsDown && !entryIsLowerThanPrevious) {
|
207
185
|
activate(entry);
|
208
186
|
}
|
209
187
|
}
|
210
188
|
}
|
211
|
-
|
212
189
|
_initializeTargetsAndObservables() {
|
213
190
|
this._targetLinks = new Map();
|
214
191
|
this._observableSections = new Map();
|
215
|
-
const targetLinks =
|
216
|
-
|
192
|
+
const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);
|
217
193
|
for (const anchor of targetLinks) {
|
218
194
|
// ensure that the anchor has an id and is not disabled
|
219
|
-
if (!anchor.hash ||
|
195
|
+
if (!anchor.hash || index_js.isDisabled(anchor)) {
|
220
196
|
continue;
|
221
197
|
}
|
198
|
+
const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);
|
222
199
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
this._targetLinks.set(anchor.hash, anchor);
|
227
|
-
|
200
|
+
// ensure that the observableSection exists & is visible
|
201
|
+
if (index_js.isVisible(observableSection)) {
|
202
|
+
this._targetLinks.set(decodeURI(anchor.hash), anchor);
|
228
203
|
this._observableSections.set(anchor.hash, observableSection);
|
229
204
|
}
|
230
205
|
}
|
231
206
|
}
|
232
|
-
|
233
207
|
_process(target) {
|
234
208
|
if (this._activeTarget === target) {
|
235
209
|
return;
|
236
210
|
}
|
237
|
-
|
238
211
|
this._clearActiveClass(this._config.target);
|
239
|
-
|
240
212
|
this._activeTarget = target;
|
241
213
|
target.classList.add(CLASS_NAME_ACTIVE);
|
242
|
-
|
243
214
|
this._activateParents(target);
|
244
|
-
|
245
|
-
EventHandler__default.default.trigger(this._element, EVENT_ACTIVATE, {
|
215
|
+
EventHandler.trigger(this._element, EVENT_ACTIVATE, {
|
246
216
|
relatedTarget: target
|
247
217
|
});
|
248
218
|
}
|
249
|
-
|
250
219
|
_activateParents(target) {
|
251
220
|
// Activate dropdown parents
|
252
221
|
if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
253
|
-
|
222
|
+
SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
|
254
223
|
return;
|
255
224
|
}
|
256
|
-
|
257
|
-
for (const listGroup of SelectorEngine__default.default.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
225
|
+
for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
258
226
|
// Set triggered links parents as active
|
259
227
|
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
260
|
-
for (const item of
|
228
|
+
for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
|
261
229
|
item.classList.add(CLASS_NAME_ACTIVE);
|
262
230
|
}
|
263
231
|
}
|
264
232
|
}
|
265
|
-
|
266
233
|
_clearActiveClass(parent) {
|
267
234
|
parent.classList.remove(CLASS_NAME_ACTIVE);
|
268
|
-
const activeNodes =
|
269
|
-
|
235
|
+
const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
|
270
236
|
for (const node of activeNodes) {
|
271
237
|
node.classList.remove(CLASS_NAME_ACTIVE);
|
272
238
|
}
|
273
|
-
}
|
274
|
-
|
239
|
+
}
|
275
240
|
|
241
|
+
// Static
|
276
242
|
static jQueryInterface(config) {
|
277
243
|
return this.each(function () {
|
278
244
|
const data = ScrollSpy.getOrCreateInstance(this, config);
|
279
|
-
|
280
245
|
if (typeof config !== 'string') {
|
281
246
|
return;
|
282
247
|
}
|
283
|
-
|
284
248
|
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
285
249
|
throw new TypeError(`No method named "${config}"`);
|
286
250
|
}
|
287
|
-
|
288
251
|
data[config]();
|
289
252
|
});
|
290
253
|
}
|
291
|
-
|
292
254
|
}
|
255
|
+
|
293
256
|
/**
|
294
257
|
* Data API implementation
|
295
258
|
*/
|
296
259
|
|
297
|
-
|
298
|
-
|
299
|
-
for (const spy of SelectorEngine__default.default.find(SELECTOR_DATA_SPY)) {
|
260
|
+
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
261
|
+
for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
|
300
262
|
ScrollSpy.getOrCreateInstance(spy);
|
301
263
|
}
|
302
264
|
});
|
265
|
+
|
303
266
|
/**
|
304
267
|
* jQuery
|
305
268
|
*/
|
306
269
|
|
307
|
-
|
270
|
+
index_js.defineJQueryPlugin(ScrollSpy);
|
308
271
|
|
309
272
|
return ScrollSpy;
|
310
273
|
|