bootstrap 5.1.1 → 5.2.0
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 +18 -153
- data/assets/javascripts/bootstrap/base-component.js +44 -127
- data/assets/javascripts/bootstrap/button.js +16 -80
- data/assets/javascripts/bootstrap/carousel.js +225 -497
- data/assets/javascripts/bootstrap/collapse.js +79 -262
- data/assets/javascripts/bootstrap/dom/data.js +6 -8
- data/assets/javascripts/bootstrap/dom/event-handler.js +95 -133
- data/assets/javascripts/bootstrap/dom/manipulator.js +25 -29
- data/assets/javascripts/bootstrap/dom/selector-engine.js +17 -59
- data/assets/javascripts/bootstrap/dropdown.js +124 -342
- data/assets/javascripts/bootstrap/modal.js +122 -767
- data/assets/javascripts/bootstrap/offcanvas.js +102 -671
- data/assets/javascripts/bootstrap/popover.js +42 -124
- data/assets/javascripts/bootstrap/scrollspy.js +186 -269
- data/assets/javascripts/bootstrap/tab.js +222 -221
- data/assets/javascripts/bootstrap/toast.js +41 -227
- data/assets/javascripts/bootstrap/tooltip.js +283 -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 +16 -7
- data/assets/javascripts/bootstrap.js +2094 -1891
- 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 +52 -24
- 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 +3 -0
- data/assets/stylesheets/bootstrap/_buttons.scss +97 -22
- 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 +83 -75
- data/assets/stylesheets/bootstrap/_functions.scss +7 -7
- data/assets/stylesheets/bootstrap/_grid.scss +3 -3
- data/assets/stylesheets/bootstrap/_helpers.scss +1 -0
- data/assets/stylesheets/bootstrap/_list-group.scss +44 -27
- 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 +91 -150
- data/assets/stylesheets/bootstrap/_offcanvas.scss +119 -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 +38 -25
- data/assets/stylesheets/bootstrap/_toasts.scss +35 -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 +118 -124
- data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +3 -6
- data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +14 -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 +2 -1
- data/assets/stylesheets/bootstrap/forms/_input-group.scss +15 -7
- 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 +8 -0
- data/assets/stylesheets/bootstrap/mixins/_gradients.scss +1 -1
- data/assets/stylesheets/bootstrap/mixins/_grid.scss +13 -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 +12 -4
- data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +1 -1
- data/bootstrap.gemspec +1 -1
- data/lib/bootstrap/version.rb +2 -2
- data/tasks/updater/js.rb +9 -4
- metadata +16 -4
|
@@ -1,215 +1,80 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Bootstrap scrollspy.js v5.
|
|
3
|
-
* Copyright 2011-
|
|
2
|
+
* Bootstrap scrollspy.js v5.2.0 (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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
|
14
|
+
const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
|
|
15
|
+
const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
|
|
16
|
+
const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* --------------------------------------------------------------------------
|
|
21
|
-
* Bootstrap (v5.
|
|
20
|
+
* Bootstrap (v5.2.0): scrollspy.js
|
|
22
21
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
23
22
|
* --------------------------------------------------------------------------
|
|
24
23
|
*/
|
|
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
24
|
/**
|
|
154
|
-
* --------------------------------------------------------------------------
|
|
155
|
-
* Bootstrap (v5.1.1): scrollspy.js
|
|
156
|
-
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
157
|
-
* --------------------------------------------------------------------------
|
|
158
|
-
*/
|
|
159
|
-
/**
|
|
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
|
+
};
|
|
53
|
+
const DefaultType = {
|
|
54
|
+
offset: '(number|null)',
|
|
55
|
+
// TODO v6 @deprecated, keep it for backwards compatibility reasons
|
|
56
|
+
rootMargin: 'string',
|
|
57
|
+
smoothScroll: 'boolean',
|
|
58
|
+
target: 'element'
|
|
59
|
+
};
|
|
194
60
|
/**
|
|
195
|
-
*
|
|
196
|
-
* Class Definition
|
|
197
|
-
* ------------------------------------------------------------------------
|
|
61
|
+
* Class definition
|
|
198
62
|
*/
|
|
199
63
|
|
|
200
|
-
class ScrollSpy extends BaseComponent__default
|
|
64
|
+
class ScrollSpy extends BaseComponent__default.default {
|
|
201
65
|
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();
|
|
66
|
+
super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper
|
|
211
67
|
|
|
212
|
-
this.
|
|
68
|
+
this._targetLinks = new Map();
|
|
69
|
+
this._observableSections = new Map();
|
|
70
|
+
this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
|
|
71
|
+
this._activeTarget = null;
|
|
72
|
+
this._observer = null;
|
|
73
|
+
this._previousScrollData = {
|
|
74
|
+
visibleEntryTop: 0,
|
|
75
|
+
parentScrollTop: 0
|
|
76
|
+
};
|
|
77
|
+
this.refresh(); // initialize
|
|
213
78
|
} // Getters
|
|
214
79
|
|
|
215
80
|
|
|
@@ -217,135 +82,190 @@
|
|
|
217
82
|
return Default;
|
|
218
83
|
}
|
|
219
84
|
|
|
85
|
+
static get DefaultType() {
|
|
86
|
+
return DefaultType;
|
|
87
|
+
}
|
|
88
|
+
|
|
220
89
|
static get NAME() {
|
|
221
90
|
return NAME;
|
|
222
91
|
} // Public
|
|
223
92
|
|
|
224
93
|
|
|
225
94
|
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
|
-
}
|
|
95
|
+
this._initializeTargetsAndObservables();
|
|
244
96
|
|
|
245
|
-
|
|
246
|
-
}).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {
|
|
247
|
-
this._offsets.push(item[0]);
|
|
97
|
+
this._maybeEnableSmoothScroll();
|
|
248
98
|
|
|
249
|
-
|
|
250
|
-
|
|
99
|
+
if (this._observer) {
|
|
100
|
+
this._observer.disconnect();
|
|
101
|
+
} else {
|
|
102
|
+
this._observer = this._getNewObserver();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const section of this._observableSections.values()) {
|
|
106
|
+
this._observer.observe(section);
|
|
107
|
+
}
|
|
251
108
|
}
|
|
252
109
|
|
|
253
110
|
dispose() {
|
|
254
|
-
|
|
111
|
+
this._observer.disconnect();
|
|
112
|
+
|
|
255
113
|
super.dispose();
|
|
256
114
|
} // Private
|
|
257
115
|
|
|
258
116
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
...(typeof config === 'object' && config ? config : {})
|
|
263
|
-
};
|
|
264
|
-
config.target = getElement(config.target) || document.documentElement;
|
|
265
|
-
typeCheckConfig(NAME, config, DefaultType);
|
|
117
|
+
_configAfterMerge(config) {
|
|
118
|
+
// TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
|
|
119
|
+
config.target = index.getElement(config.target) || document.body;
|
|
266
120
|
return config;
|
|
267
121
|
}
|
|
268
122
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
123
|
+
_maybeEnableSmoothScroll() {
|
|
124
|
+
if (!this._config.smoothScroll) {
|
|
125
|
+
return;
|
|
126
|
+
} // unregister any previous listeners
|
|
272
127
|
|
|
273
|
-
_getScrollHeight() {
|
|
274
|
-
return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
|
|
275
|
-
}
|
|
276
128
|
|
|
277
|
-
|
|
278
|
-
|
|
129
|
+
EventHandler__default.default.off(this._config.target, EVENT_CLICK);
|
|
130
|
+
EventHandler__default.default.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
|
|
131
|
+
const observableSection = this._observableSections.get(event.target.hash);
|
|
132
|
+
|
|
133
|
+
if (observableSection) {
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
const root = this._rootElement || window;
|
|
136
|
+
const height = observableSection.offsetTop - this._element.offsetTop;
|
|
137
|
+
|
|
138
|
+
if (root.scrollTo) {
|
|
139
|
+
root.scrollTo({
|
|
140
|
+
top: height,
|
|
141
|
+
behavior: 'smooth'
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
} // Chrome 60 doesn't support `scrollTo`
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
root.scrollTop = height;
|
|
148
|
+
}
|
|
149
|
+
});
|
|
279
150
|
}
|
|
280
151
|
|
|
281
|
-
|
|
282
|
-
const
|
|
152
|
+
_getNewObserver() {
|
|
153
|
+
const options = {
|
|
154
|
+
root: this._rootElement,
|
|
155
|
+
threshold: [0.1, 0.5, 1],
|
|
156
|
+
rootMargin: this._getRootMargin()
|
|
157
|
+
};
|
|
158
|
+
return new IntersectionObserver(entries => this._observerCallback(entries), options);
|
|
159
|
+
} // The logic of selection
|
|
160
|
+
|
|
283
161
|
|
|
284
|
-
|
|
162
|
+
_observerCallback(entries) {
|
|
163
|
+
const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
|
|
285
164
|
|
|
286
|
-
const
|
|
165
|
+
const activate = entry => {
|
|
166
|
+
this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
|
|
287
167
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
168
|
+
this._process(targetElement(entry));
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
|
|
172
|
+
const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
|
|
173
|
+
this._previousScrollData.parentScrollTop = parentScrollTop;
|
|
174
|
+
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
if (!entry.isIntersecting) {
|
|
177
|
+
this._activeTarget = null;
|
|
291
178
|
|
|
292
|
-
|
|
293
|
-
const target = this._targets[this._targets.length - 1];
|
|
179
|
+
this._clearActiveClass(targetElement(entry));
|
|
294
180
|
|
|
295
|
-
|
|
296
|
-
this._activate(target);
|
|
181
|
+
continue;
|
|
297
182
|
}
|
|
298
183
|
|
|
299
|
-
|
|
300
|
-
}
|
|
184
|
+
const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop
|
|
301
185
|
|
|
302
|
-
|
|
303
|
-
|
|
186
|
+
if (userScrollsDown && entryIsLowerThanPrevious) {
|
|
187
|
+
activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
|
|
304
188
|
|
|
305
|
-
|
|
189
|
+
if (!parentScrollTop) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
306
192
|
|
|
307
|
-
|
|
308
|
-
|
|
193
|
+
continue;
|
|
194
|
+
} // if we are scrolling up, pick the smallest offsetTop
|
|
309
195
|
|
|
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
196
|
|
|
313
|
-
if (
|
|
314
|
-
|
|
197
|
+
if (!userScrollsDown && !entryIsLowerThanPrevious) {
|
|
198
|
+
activate(entry);
|
|
315
199
|
}
|
|
316
200
|
}
|
|
201
|
+
} // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
_getRootMargin() {
|
|
205
|
+
return this._config.offset ? `${this._config.offset}px 0px -30%` : this._config.rootMargin;
|
|
317
206
|
}
|
|
318
207
|
|
|
319
|
-
|
|
320
|
-
this.
|
|
208
|
+
_initializeTargetsAndObservables() {
|
|
209
|
+
this._targetLinks = new Map();
|
|
210
|
+
this._observableSections = new Map();
|
|
211
|
+
const targetLinks = SelectorEngine__default.default.find(SELECTOR_TARGET_LINKS, this._config.target);
|
|
321
212
|
|
|
322
|
-
|
|
213
|
+
for (const anchor of targetLinks) {
|
|
214
|
+
// ensure that the anchor has an id and is not disabled
|
|
215
|
+
if (!anchor.hash || index.isDisabled(anchor)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
323
218
|
|
|
324
|
-
|
|
325
|
-
const link = SelectorEngine__default['default'].findOne(queries.join(','), this._config.target);
|
|
326
|
-
link.classList.add(CLASS_NAME_ACTIVE);
|
|
219
|
+
const observableSection = SelectorEngine__default.default.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible
|
|
327
220
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
});
|
|
221
|
+
if (index.isVisible(observableSection)) {
|
|
222
|
+
this._targetLinks.set(anchor.hash, anchor);
|
|
223
|
+
|
|
224
|
+
this._observableSections.set(anchor.hash, observableSection);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
_process(target) {
|
|
230
|
+
if (this._activeTarget === target) {
|
|
231
|
+
return;
|
|
340
232
|
}
|
|
341
233
|
|
|
342
|
-
|
|
234
|
+
this._clearActiveClass(this._config.target);
|
|
235
|
+
|
|
236
|
+
this._activeTarget = target;
|
|
237
|
+
target.classList.add(CLASS_NAME_ACTIVE);
|
|
238
|
+
|
|
239
|
+
this._activateParents(target);
|
|
240
|
+
|
|
241
|
+
EventHandler__default.default.trigger(this._element, EVENT_ACTIVATE, {
|
|
343
242
|
relatedTarget: target
|
|
344
243
|
});
|
|
345
244
|
}
|
|
346
245
|
|
|
347
|
-
|
|
348
|
-
|
|
246
|
+
_activateParents(target) {
|
|
247
|
+
// Activate dropdown parents
|
|
248
|
+
if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
|
249
|
+
SelectorEngine__default.default.findOne(SELECTOR_DROPDOWN_TOGGLE, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
for (const listGroup of SelectorEngine__default.default.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
|
254
|
+
// Set triggered links parents as active
|
|
255
|
+
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
|
256
|
+
for (const item of SelectorEngine__default.default.prev(listGroup, SELECTOR_LINK_ITEMS)) {
|
|
257
|
+
item.classList.add(CLASS_NAME_ACTIVE);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
_clearActiveClass(parent) {
|
|
263
|
+
parent.classList.remove(CLASS_NAME_ACTIVE);
|
|
264
|
+
const activeNodes = SelectorEngine__default.default.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
|
|
265
|
+
|
|
266
|
+
for (const node of activeNodes) {
|
|
267
|
+
node.classList.remove(CLASS_NAME_ACTIVE);
|
|
268
|
+
}
|
|
349
269
|
} // Static
|
|
350
270
|
|
|
351
271
|
|
|
@@ -357,7 +277,7 @@
|
|
|
357
277
|
return;
|
|
358
278
|
}
|
|
359
279
|
|
|
360
|
-
if (
|
|
280
|
+
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
|
361
281
|
throw new TypeError(`No method named "${config}"`);
|
|
362
282
|
}
|
|
363
283
|
|
|
@@ -367,24 +287,21 @@
|
|
|
367
287
|
|
|
368
288
|
}
|
|
369
289
|
/**
|
|
370
|
-
*
|
|
371
|
-
* Data Api implementation
|
|
372
|
-
* ------------------------------------------------------------------------
|
|
290
|
+
* Data API implementation
|
|
373
291
|
*/
|
|
374
292
|
|
|
375
293
|
|
|
376
|
-
EventHandler__default
|
|
377
|
-
SelectorEngine__default
|
|
294
|
+
EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
|
|
295
|
+
for (const spy of SelectorEngine__default.default.find(SELECTOR_DATA_SPY)) {
|
|
296
|
+
ScrollSpy.getOrCreateInstance(spy);
|
|
297
|
+
}
|
|
378
298
|
});
|
|
379
299
|
/**
|
|
380
|
-
* ------------------------------------------------------------------------
|
|
381
300
|
* jQuery
|
|
382
|
-
* ------------------------------------------------------------------------
|
|
383
|
-
* add .ScrollSpy to jQuery only if jQuery is present
|
|
384
301
|
*/
|
|
385
302
|
|
|
386
|
-
defineJQueryPlugin(ScrollSpy);
|
|
303
|
+
index.defineJQueryPlugin(ScrollSpy);
|
|
387
304
|
|
|
388
305
|
return ScrollSpy;
|
|
389
306
|
|
|
390
|
-
}))
|
|
307
|
+
}));
|