bootstrap 5.1.3 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -4
- data/assets/javascripts/bootstrap/alert.js +11 -146
- data/assets/javascripts/bootstrap/base-component.js +37 -120
- data/assets/javascripts/bootstrap/button.js +10 -74
- data/assets/javascripts/bootstrap/carousel.js +213 -485
- data/assets/javascripts/bootstrap/collapse.js +65 -249
- data/assets/javascripts/bootstrap/dom/data.js +3 -5
- data/assets/javascripts/bootstrap/dom/event-handler.js +94 -132
- data/assets/javascripts/bootstrap/dom/manipulator.js +23 -27
- data/assets/javascripts/bootstrap/dom/selector-engine.js +16 -58
- data/assets/javascripts/bootstrap/dropdown.js +103 -317
- data/assets/javascripts/bootstrap/modal.js +107 -749
- data/assets/javascripts/bootstrap/offcanvas.js +90 -659
- data/assets/javascripts/bootstrap/popover.js +36 -118
- data/assets/javascripts/bootstrap/scrollspy.js +183 -262
- data/assets/javascripts/bootstrap/tab.js +215 -214
- data/assets/javascripts/bootstrap/toast.js +36 -218
- data/assets/javascripts/bootstrap/tooltip.js +280 -629
- data/assets/javascripts/bootstrap/util/backdrop.js +165 -0
- data/assets/javascripts/bootstrap/util/component-functions.js +46 -0
- data/assets/javascripts/bootstrap/util/config.js +79 -0
- data/assets/javascripts/bootstrap/util/focustrap.js +129 -0
- data/assets/javascripts/bootstrap/util/index.js +350 -0
- data/assets/javascripts/bootstrap/util/sanitizer.js +122 -0
- data/assets/javascripts/bootstrap/util/scrollbar.js +138 -0
- data/assets/javascripts/bootstrap/util/swipe.js +155 -0
- data/assets/javascripts/bootstrap/util/template-factory.js +177 -0
- data/assets/javascripts/bootstrap-global-this-define.js +1 -1
- data/assets/javascripts/bootstrap-sprockets.js +17 -8
- data/assets/javascripts/bootstrap.js +2093 -1881
- data/assets/javascripts/bootstrap.min.js +3 -3
- data/assets/stylesheets/_bootstrap-grid.scss +3 -6
- data/assets/stylesheets/_bootstrap-reboot.scss +3 -7
- data/assets/stylesheets/_bootstrap.scss +4 -6
- data/assets/stylesheets/bootstrap/_accordion.scss +56 -25
- data/assets/stylesheets/bootstrap/_alert.scss +18 -4
- data/assets/stylesheets/bootstrap/_badge.scss +14 -5
- data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -10
- data/assets/stylesheets/bootstrap/_button-group.scss +4 -1
- data/assets/stylesheets/bootstrap/_buttons.scss +125 -29
- data/assets/stylesheets/bootstrap/_card.scss +55 -37
- data/assets/stylesheets/bootstrap/_close.scss +1 -1
- data/assets/stylesheets/bootstrap/_containers.scss +1 -1
- data/assets/stylesheets/bootstrap/_dropdown.scss +85 -76
- data/assets/stylesheets/bootstrap/_functions.scss +8 -8
- data/assets/stylesheets/bootstrap/_grid.scss +3 -3
- data/assets/stylesheets/bootstrap/_helpers.scss +1 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +48 -30
- data/assets/stylesheets/bootstrap/_maps.scss +54 -0
- data/assets/stylesheets/bootstrap/_modal.scss +71 -43
- data/assets/stylesheets/bootstrap/_nav.scss +53 -20
- data/assets/stylesheets/bootstrap/_navbar.scss +93 -150
- data/assets/stylesheets/bootstrap/_offcanvas.scss +120 -59
- data/assets/stylesheets/bootstrap/_pagination.scss +66 -21
- data/assets/stylesheets/bootstrap/_placeholders.scss +1 -1
- data/assets/stylesheets/bootstrap/_popover.scss +90 -52
- data/assets/stylesheets/bootstrap/_progress.scss +20 -9
- data/assets/stylesheets/bootstrap/_reboot.scss +25 -40
- data/assets/stylesheets/bootstrap/_root.scss +40 -21
- data/assets/stylesheets/bootstrap/_spinners.scss +38 -22
- data/assets/stylesheets/bootstrap/_tables.scss +32 -23
- data/assets/stylesheets/bootstrap/_toasts.scss +38 -16
- data/assets/stylesheets/bootstrap/_tooltip.scss +61 -56
- data/assets/stylesheets/bootstrap/_type.scss +2 -0
- data/assets/stylesheets/bootstrap/_utilities.scss +43 -26
- data/assets/stylesheets/bootstrap/_variables.scss +128 -135
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +3 -6
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +15 -3
- data/assets/stylesheets/bootstrap/forms/_form-check.scss +28 -5
- data/assets/stylesheets/bootstrap/forms/_form-control.scss +12 -37
- data/assets/stylesheets/bootstrap/forms/_form-select.scss +0 -1
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +19 -8
- data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +10 -0
- data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +2 -2
- data/assets/stylesheets/bootstrap/helpers/_position.scss +7 -1
- data/assets/stylesheets/bootstrap/helpers/_ratio.scss +2 -2
- data/assets/stylesheets/bootstrap/helpers/_vr.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_alert.scss +7 -3
- data/assets/stylesheets/bootstrap/mixins/_banner.scss +9 -0
- data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +8 -8
- data/assets/stylesheets/bootstrap/mixins/_buttons.scss +32 -95
- data/assets/stylesheets/bootstrap/mixins/_container.scss +4 -2
- data/assets/stylesheets/bootstrap/mixins/_forms.scss +18 -10
- data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +12 -12
- data/assets/stylesheets/bootstrap/mixins/_pagination.scss +4 -25
- data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +12 -9
- data/assets/stylesheets/bootstrap/mixins/_utilities.scss +13 -5
- data/bootstrap.gemspec +1 -1
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +10 -5
- data/tasks/updater.rb +2 -2
- metadata +16 -4
|
@@ -1,215 +1,82 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Bootstrap scrollspy.js v5.
|
|
3
|
-
* Copyright 2011-
|
|
2
|
+
* Bootstrap scrollspy.js v5.2.2 (https://getbootstrap.com/)
|
|
3
|
+
* Copyright 2011-2022 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.
|
|
10
|
-
})(this, (function (
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./util/index'), require('./dom/event-handler'), require('./dom/selector-engine'), require('./base-component')) :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(['./util/index', './dom/event-handler', './dom/selector-engine', './base-component'], factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Scrollspy = factory(global.Index, global.EventHandler, global.SelectorEngine, global.BaseComponent));
|
|
10
|
+
})(this, (function (index, EventHandler, SelectorEngine, BaseComponent) { 'use strict';
|
|
11
11
|
|
|
12
12
|
const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
|
|
13
13
|
|
|
14
14
|
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
-
const Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
|
|
16
15
|
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
|
17
16
|
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* --------------------------------------------------------------------------
|
|
21
|
-
* Bootstrap (v5.
|
|
22
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
23
|
-
* --------------------------------------------------------------------------
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
const toType = obj => {
|
|
27
|
-
if (obj === null || obj === undefined) {
|
|
28
|
-
return `${obj}`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const getSelector = element => {
|
|
35
|
-
let selector = element.getAttribute('data-bs-target');
|
|
36
|
-
|
|
37
|
-
if (!selector || selector === '#') {
|
|
38
|
-
let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
|
|
39
|
-
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
|
40
|
-
// `document.querySelector` will rightfully complain it is invalid.
|
|
41
|
-
// See https://github.com/twbs/bootstrap/issues/32273
|
|
42
|
-
|
|
43
|
-
if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
|
|
44
|
-
return null;
|
|
45
|
-
} // Just in case some CMS puts out a full URL with the anchor appended
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
|
|
49
|
-
hrefAttr = `#${hrefAttr.split('#')[1]}`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return selector;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const getSelectorFromElement = element => {
|
|
59
|
-
const selector = getSelector(element);
|
|
60
|
-
|
|
61
|
-
if (selector) {
|
|
62
|
-
return document.querySelector(selector) ? selector : null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
const isElement = obj => {
|
|
69
|
-
if (!obj || typeof obj !== 'object') {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (typeof obj.jquery !== 'undefined') {
|
|
74
|
-
obj = obj[0];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return typeof obj.nodeType !== 'undefined';
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const getElement = obj => {
|
|
81
|
-
if (isElement(obj)) {
|
|
82
|
-
// it's a jQuery object or a node element
|
|
83
|
-
return obj.jquery ? obj[0] : obj;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (typeof obj === 'string' && obj.length > 0) {
|
|
87
|
-
return document.querySelector(obj);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return null;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const typeCheckConfig = (componentName, config, configTypes) => {
|
|
94
|
-
Object.keys(configTypes).forEach(property => {
|
|
95
|
-
const expectedTypes = configTypes[property];
|
|
96
|
-
const value = config[property];
|
|
97
|
-
const valueType = value && isElement(value) ? 'element' : toType(value);
|
|
98
|
-
|
|
99
|
-
if (!new RegExp(expectedTypes).test(valueType)) {
|
|
100
|
-
throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const getjQuery = () => {
|
|
106
|
-
const {
|
|
107
|
-
jQuery
|
|
108
|
-
} = window;
|
|
109
|
-
|
|
110
|
-
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
|
111
|
-
return jQuery;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return null;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
const DOMContentLoadedCallbacks = [];
|
|
118
|
-
|
|
119
|
-
const onDOMContentLoaded = callback => {
|
|
120
|
-
if (document.readyState === 'loading') {
|
|
121
|
-
// add listener on the first call when the document is in loading state
|
|
122
|
-
if (!DOMContentLoadedCallbacks.length) {
|
|
123
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
124
|
-
DOMContentLoadedCallbacks.forEach(callback => callback());
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
DOMContentLoadedCallbacks.push(callback);
|
|
129
|
-
} else {
|
|
130
|
-
callback();
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const defineJQueryPlugin = plugin => {
|
|
135
|
-
onDOMContentLoaded(() => {
|
|
136
|
-
const $ = getjQuery();
|
|
137
|
-
/* istanbul ignore if */
|
|
138
|
-
|
|
139
|
-
if ($) {
|
|
140
|
-
const name = plugin.NAME;
|
|
141
|
-
const JQUERY_NO_CONFLICT = $.fn[name];
|
|
142
|
-
$.fn[name] = plugin.jQueryInterface;
|
|
143
|
-
$.fn[name].Constructor = plugin;
|
|
144
|
-
|
|
145
|
-
$.fn[name].noConflict = () => {
|
|
146
|
-
$.fn[name] = JQUERY_NO_CONFLICT;
|
|
147
|
-
return plugin.jQueryInterface;
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* --------------------------------------------------------------------------
|
|
155
|
-
* Bootstrap (v5.1.3): scrollspy.js
|
|
20
|
+
* Bootstrap (v5.2.2): scrollspy.js
|
|
156
21
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
157
22
|
* --------------------------------------------------------------------------
|
|
158
23
|
*/
|
|
159
24
|
/**
|
|
160
|
-
* ------------------------------------------------------------------------
|
|
161
25
|
* Constants
|
|
162
|
-
* ------------------------------------------------------------------------
|
|
163
26
|
*/
|
|
164
27
|
|
|
165
28
|
const NAME = 'scrollspy';
|
|
166
29
|
const DATA_KEY = 'bs.scrollspy';
|
|
167
30
|
const EVENT_KEY = `.${DATA_KEY}`;
|
|
168
31
|
const DATA_API_KEY = '.data-api';
|
|
169
|
-
const Default = {
|
|
170
|
-
offset: 10,
|
|
171
|
-
method: 'auto',
|
|
172
|
-
target: ''
|
|
173
|
-
};
|
|
174
|
-
const DefaultType = {
|
|
175
|
-
offset: 'number',
|
|
176
|
-
method: 'string',
|
|
177
|
-
target: '(string|element)'
|
|
178
|
-
};
|
|
179
32
|
const EVENT_ACTIVATE = `activate${EVENT_KEY}`;
|
|
180
|
-
const
|
|
33
|
+
const EVENT_CLICK = `click${EVENT_KEY}`;
|
|
181
34
|
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
|
|
182
35
|
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
|
|
183
36
|
const CLASS_NAME_ACTIVE = 'active';
|
|
184
37
|
const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
|
|
38
|
+
const SELECTOR_TARGET_LINKS = '[href]';
|
|
185
39
|
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
|
|
186
40
|
const SELECTOR_NAV_LINKS = '.nav-link';
|
|
187
41
|
const SELECTOR_NAV_ITEMS = '.nav-item';
|
|
188
42
|
const SELECTOR_LIST_ITEMS = '.list-group-item';
|
|
189
|
-
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${
|
|
43
|
+
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
|
|
190
44
|
const SELECTOR_DROPDOWN = '.dropdown';
|
|
191
45
|
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
|
|
192
|
-
const
|
|
193
|
-
|
|
46
|
+
const Default = {
|
|
47
|
+
offset: null,
|
|
48
|
+
// TODO: v6 @deprecated, keep it for backwards compatibility reasons
|
|
49
|
+
rootMargin: '0px 0px -25%',
|
|
50
|
+
smoothScroll: false,
|
|
51
|
+
target: null,
|
|
52
|
+
threshold: [0.1, 0.5, 1]
|
|
53
|
+
};
|
|
54
|
+
const DefaultType = {
|
|
55
|
+
offset: '(number|null)',
|
|
56
|
+
// TODO v6 @deprecated, keep it for backwards compatibility reasons
|
|
57
|
+
rootMargin: 'string',
|
|
58
|
+
smoothScroll: 'boolean',
|
|
59
|
+
target: 'element',
|
|
60
|
+
threshold: 'array'
|
|
61
|
+
};
|
|
194
62
|
/**
|
|
195
|
-
*
|
|
196
|
-
* Class Definition
|
|
197
|
-
* ------------------------------------------------------------------------
|
|
63
|
+
* Class definition
|
|
198
64
|
*/
|
|
199
65
|
|
|
200
66
|
class ScrollSpy extends BaseComponent__default.default {
|
|
201
67
|
constructor(element, config) {
|
|
202
|
-
super(element);
|
|
203
|
-
this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
|
|
204
|
-
this._config = this._getConfig(config);
|
|
205
|
-
this._offsets = [];
|
|
206
|
-
this._targets = [];
|
|
207
|
-
this._activeTarget = null;
|
|
208
|
-
this._scrollHeight = 0;
|
|
209
|
-
EventHandler__default.default.on(this._scrollElement, EVENT_SCROLL, () => this._process());
|
|
210
|
-
this.refresh();
|
|
68
|
+
super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper
|
|
211
69
|
|
|
212
|
-
this.
|
|
70
|
+
this._targetLinks = new Map();
|
|
71
|
+
this._observableSections = new Map();
|
|
72
|
+
this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
|
|
73
|
+
this._activeTarget = null;
|
|
74
|
+
this._observer = null;
|
|
75
|
+
this._previousScrollData = {
|
|
76
|
+
visibleEntryTop: 0,
|
|
77
|
+
parentScrollTop: 0
|
|
78
|
+
};
|
|
79
|
+
this.refresh(); // initialize
|
|
213
80
|
} // Getters
|
|
214
81
|
|
|
215
82
|
|
|
@@ -217,135 +84,192 @@
|
|
|
217
84
|
return Default;
|
|
218
85
|
}
|
|
219
86
|
|
|
87
|
+
static get DefaultType() {
|
|
88
|
+
return DefaultType;
|
|
89
|
+
}
|
|
90
|
+
|
|
220
91
|
static get NAME() {
|
|
221
92
|
return NAME;
|
|
222
93
|
} // Public
|
|
223
94
|
|
|
224
95
|
|
|
225
96
|
refresh() {
|
|
226
|
-
|
|
227
|
-
const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
|
|
228
|
-
const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
|
|
229
|
-
this._offsets = [];
|
|
230
|
-
this._targets = [];
|
|
231
|
-
this._scrollHeight = this._getScrollHeight();
|
|
232
|
-
const targets = SelectorEngine__default.default.find(SELECTOR_LINK_ITEMS, this._config.target);
|
|
233
|
-
targets.map(element => {
|
|
234
|
-
const targetSelector = getSelectorFromElement(element);
|
|
235
|
-
const target = targetSelector ? SelectorEngine__default.default.findOne(targetSelector) : null;
|
|
236
|
-
|
|
237
|
-
if (target) {
|
|
238
|
-
const targetBCR = target.getBoundingClientRect();
|
|
239
|
-
|
|
240
|
-
if (targetBCR.width || targetBCR.height) {
|
|
241
|
-
return [Manipulator__default.default[offsetMethod](target).top + offsetBase, targetSelector];
|
|
242
|
-
}
|
|
243
|
-
}
|
|
97
|
+
this._initializeTargetsAndObservables();
|
|
244
98
|
|
|
245
|
-
|
|
246
|
-
}).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {
|
|
247
|
-
this._offsets.push(item[0]);
|
|
99
|
+
this._maybeEnableSmoothScroll();
|
|
248
100
|
|
|
249
|
-
|
|
250
|
-
|
|
101
|
+
if (this._observer) {
|
|
102
|
+
this._observer.disconnect();
|
|
103
|
+
} else {
|
|
104
|
+
this._observer = this._getNewObserver();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const section of this._observableSections.values()) {
|
|
108
|
+
this._observer.observe(section);
|
|
109
|
+
}
|
|
251
110
|
}
|
|
252
111
|
|
|
253
112
|
dispose() {
|
|
254
|
-
|
|
113
|
+
this._observer.disconnect();
|
|
114
|
+
|
|
255
115
|
super.dispose();
|
|
256
116
|
} // Private
|
|
257
117
|
|
|
258
118
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
|
|
119
|
+
_configAfterMerge(config) {
|
|
120
|
+
// TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
|
|
121
|
+
config.target = index.getElement(config.target) || document.body; // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
|
|
122
|
+
|
|
123
|
+
config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
|
|
124
|
+
|
|
125
|
+
if (typeof config.threshold === 'string') {
|
|
126
|
+
config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
|
|
127
|
+
}
|
|
128
|
+
|
|
266
129
|
return config;
|
|
267
130
|
}
|
|
268
131
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
132
|
+
_maybeEnableSmoothScroll() {
|
|
133
|
+
if (!this._config.smoothScroll) {
|
|
134
|
+
return;
|
|
135
|
+
} // unregister any previous listeners
|
|
272
136
|
|
|
273
|
-
_getScrollHeight() {
|
|
274
|
-
return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
275
|
-
}
|
|
276
137
|
|
|
277
|
-
|
|
278
|
-
|
|
138
|
+
EventHandler__default.default.off(this._config.target, EVENT_CLICK);
|
|
139
|
+
EventHandler__default.default.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
|
|
140
|
+
const observableSection = this._observableSections.get(event.target.hash);
|
|
141
|
+
|
|
142
|
+
if (observableSection) {
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
const root = this._rootElement || window;
|
|
145
|
+
const height = observableSection.offsetTop - this._element.offsetTop;
|
|
146
|
+
|
|
147
|
+
if (root.scrollTo) {
|
|
148
|
+
root.scrollTo({
|
|
149
|
+
top: height,
|
|
150
|
+
behavior: 'smooth'
|
|
151
|
+
});
|
|
152
|
+
return;
|
|
153
|
+
} // Chrome 60 doesn't support `scrollTo`
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
root.scrollTop = height;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
279
159
|
}
|
|
280
160
|
|
|
281
|
-
|
|
282
|
-
const
|
|
161
|
+
_getNewObserver() {
|
|
162
|
+
const options = {
|
|
163
|
+
root: this._rootElement,
|
|
164
|
+
threshold: this._config.threshold,
|
|
165
|
+
rootMargin: this._config.rootMargin
|
|
166
|
+
};
|
|
167
|
+
return new IntersectionObserver(entries => this._observerCallback(entries), options);
|
|
168
|
+
} // The logic of selection
|
|
283
169
|
|
|
284
|
-
const scrollHeight = this._getScrollHeight();
|
|
285
170
|
|
|
286
|
-
|
|
171
|
+
_observerCallback(entries) {
|
|
172
|
+
const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
|
|
287
173
|
|
|
288
|
-
|
|
289
|
-
this.
|
|
290
|
-
|
|
174
|
+
const activate = entry => {
|
|
175
|
+
this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
|
|
176
|
+
|
|
177
|
+
this._process(targetElement(entry));
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
|
|
181
|
+
const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
|
|
182
|
+
this._previousScrollData.parentScrollTop = parentScrollTop;
|
|
291
183
|
|
|
292
|
-
|
|
293
|
-
|
|
184
|
+
for (const entry of entries) {
|
|
185
|
+
if (!entry.isIntersecting) {
|
|
186
|
+
this._activeTarget = null;
|
|
294
187
|
|
|
295
|
-
|
|
296
|
-
|
|
188
|
+
this._clearActiveClass(targetElement(entry));
|
|
189
|
+
|
|
190
|
+
continue;
|
|
297
191
|
}
|
|
298
192
|
|
|
299
|
-
|
|
300
|
-
}
|
|
193
|
+
const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop
|
|
301
194
|
|
|
302
|
-
|
|
303
|
-
|
|
195
|
+
if (userScrollsDown && entryIsLowerThanPrevious) {
|
|
196
|
+
activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
|
|
304
197
|
|
|
305
|
-
|
|
198
|
+
if (!parentScrollTop) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
306
201
|
|
|
307
|
-
|
|
308
|
-
|
|
202
|
+
continue;
|
|
203
|
+
} // if we are scrolling up, pick the smallest offsetTop
|
|
309
204
|
|
|
310
|
-
for (let i = this._offsets.length; i--;) {
|
|
311
|
-
const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
|
|
312
205
|
|
|
313
|
-
if (
|
|
314
|
-
|
|
206
|
+
if (!userScrollsDown && !entryIsLowerThanPrevious) {
|
|
207
|
+
activate(entry);
|
|
315
208
|
}
|
|
316
209
|
}
|
|
317
210
|
}
|
|
318
211
|
|
|
319
|
-
|
|
320
|
-
this.
|
|
212
|
+
_initializeTargetsAndObservables() {
|
|
213
|
+
this._targetLinks = new Map();
|
|
214
|
+
this._observableSections = new Map();
|
|
215
|
+
const targetLinks = SelectorEngine__default.default.find(SELECTOR_TARGET_LINKS, this._config.target);
|
|
216
|
+
|
|
217
|
+
for (const anchor of targetLinks) {
|
|
218
|
+
// ensure that the anchor has an id and is not disabled
|
|
219
|
+
if (!anchor.hash || index.isDisabled(anchor)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
321
222
|
|
|
322
|
-
|
|
223
|
+
const observableSection = SelectorEngine__default.default.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible
|
|
323
224
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
link.classList.add(CLASS_NAME_ACTIVE);
|
|
225
|
+
if (index.isVisible(observableSection)) {
|
|
226
|
+
this._targetLinks.set(anchor.hash, anchor);
|
|
327
227
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
} else {
|
|
331
|
-
SelectorEngine__default.default.parents(link, SELECTOR_NAV_LIST_GROUP).forEach(listGroup => {
|
|
332
|
-
// Set triggered links parents as active
|
|
333
|
-
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
|
334
|
-
SelectorEngine__default.default.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE)); // Handle special case when .nav-link is inside .nav-item
|
|
335
|
-
|
|
336
|
-
SelectorEngine__default.default.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {
|
|
337
|
-
SelectorEngine__default.default.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE));
|
|
338
|
-
});
|
|
339
|
-
});
|
|
228
|
+
this._observableSections.set(anchor.hash, observableSection);
|
|
229
|
+
}
|
|
340
230
|
}
|
|
231
|
+
}
|
|
341
232
|
|
|
342
|
-
|
|
233
|
+
_process(target) {
|
|
234
|
+
if (this._activeTarget === target) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
this._clearActiveClass(this._config.target);
|
|
239
|
+
|
|
240
|
+
this._activeTarget = target;
|
|
241
|
+
target.classList.add(CLASS_NAME_ACTIVE);
|
|
242
|
+
|
|
243
|
+
this._activateParents(target);
|
|
244
|
+
|
|
245
|
+
EventHandler__default.default.trigger(this._element, EVENT_ACTIVATE, {
|
|
343
246
|
relatedTarget: target
|
|
344
247
|
});
|
|
345
248
|
}
|
|
346
249
|
|
|
347
|
-
|
|
348
|
-
|
|
250
|
+
_activateParents(target) {
|
|
251
|
+
// Activate dropdown parents
|
|
252
|
+
if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
|
253
|
+
SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
for (const listGroup of SelectorEngine__default.default.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
|
258
|
+
// Set triggered links parents as active
|
|
259
|
+
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
|
260
|
+
for (const item of SelectorEngine__default.default.prev(listGroup, SELECTOR_LINK_ITEMS)) {
|
|
261
|
+
item.classList.add(CLASS_NAME_ACTIVE);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
_clearActiveClass(parent) {
|
|
267
|
+
parent.classList.remove(CLASS_NAME_ACTIVE);
|
|
268
|
+
const activeNodes = SelectorEngine__default.default.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
|
|
269
|
+
|
|
270
|
+
for (const node of activeNodes) {
|
|
271
|
+
node.classList.remove(CLASS_NAME_ACTIVE);
|
|
272
|
+
}
|
|
349
273
|
} // Static
|
|
350
274
|
|
|
351
275
|
|
|
@@ -357,7 +281,7 @@
|
|
|
357
281
|
return;
|
|
358
282
|
}
|
|
359
283
|
|
|
360
|
-
if (
|
|
284
|
+
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
|
361
285
|
throw new TypeError(`No method named "${config}"`);
|
|
362
286
|
}
|
|
363
287
|
|
|
@@ -367,23 +291,20 @@
|
|
|
367
291
|
|
|
368
292
|
}
|
|
369
293
|
/**
|
|
370
|
-
*
|
|
371
|
-
* Data Api implementation
|
|
372
|
-
* ------------------------------------------------------------------------
|
|
294
|
+
* Data API implementation
|
|
373
295
|
*/
|
|
374
296
|
|
|
375
297
|
|
|
376
298
|
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
|
|
377
|
-
SelectorEngine__default.default.find(SELECTOR_DATA_SPY)
|
|
299
|
+
for (const spy of SelectorEngine__default.default.find(SELECTOR_DATA_SPY)) {
|
|
300
|
+
ScrollSpy.getOrCreateInstance(spy);
|
|
301
|
+
}
|
|
378
302
|
});
|
|
379
303
|
/**
|
|
380
|
-
* ------------------------------------------------------------------------
|
|
381
304
|
* jQuery
|
|
382
|
-
* ------------------------------------------------------------------------
|
|
383
|
-
* add .ScrollSpy to jQuery only if jQuery is present
|
|
384
305
|
*/
|
|
385
306
|
|
|
386
|
-
defineJQueryPlugin(ScrollSpy);
|
|
307
|
+
index.defineJQueryPlugin(ScrollSpy);
|
|
387
308
|
|
|
388
309
|
return ScrollSpy;
|
|
389
310
|
|