]> git.ipfire.org Git - ipfire.org.git/blob - src/scss/bootstrap-4.0.0-alpha.6/js/dist/scrollspy.js
.gitignore: Add .vscode
[ipfire.org.git] / src / scss / bootstrap-4.0.0-alpha.6 / js / dist / scrollspy.js
1 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
2
3 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4
5 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
7 /**
8 * --------------------------------------------------------------------------
9 * Bootstrap (v4.0.0-alpha.6): scrollspy.js
10 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11 * --------------------------------------------------------------------------
12 */
13
14 var ScrollSpy = function ($) {
15
16 /**
17 * ------------------------------------------------------------------------
18 * Constants
19 * ------------------------------------------------------------------------
20 */
21
22 var NAME = 'scrollspy';
23 var VERSION = '4.0.0-alpha.6';
24 var DATA_KEY = 'bs.scrollspy';
25 var EVENT_KEY = '.' + DATA_KEY;
26 var DATA_API_KEY = '.data-api';
27 var JQUERY_NO_CONFLICT = $.fn[NAME];
28
29 var Default = {
30 offset: 10,
31 method: 'auto',
32 target: ''
33 };
34
35 var DefaultType = {
36 offset: 'number',
37 method: 'string',
38 target: '(string|element)'
39 };
40
41 var Event = {
42 ACTIVATE: 'activate' + EVENT_KEY,
43 SCROLL: 'scroll' + EVENT_KEY,
44 LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY
45 };
46
47 var ClassName = {
48 DROPDOWN_ITEM: 'dropdown-item',
49 DROPDOWN_MENU: 'dropdown-menu',
50 NAV_LINK: 'nav-link',
51 NAV: 'nav',
52 ACTIVE: 'active'
53 };
54
55 var Selector = {
56 DATA_SPY: '[data-spy="scroll"]',
57 ACTIVE: '.active',
58 LIST_ITEM: '.list-item',
59 LI: 'li',
60 LI_DROPDOWN: 'li.dropdown',
61 NAV_LINKS: '.nav-link',
62 DROPDOWN: '.dropdown',
63 DROPDOWN_ITEMS: '.dropdown-item',
64 DROPDOWN_TOGGLE: '.dropdown-toggle'
65 };
66
67 var OffsetMethod = {
68 OFFSET: 'offset',
69 POSITION: 'position'
70 };
71
72 /**
73 * ------------------------------------------------------------------------
74 * Class Definition
75 * ------------------------------------------------------------------------
76 */
77
78 var ScrollSpy = function () {
79 function ScrollSpy(element, config) {
80 var _this = this;
81
82 _classCallCheck(this, ScrollSpy);
83
84 this._element = element;
85 this._scrollElement = element.tagName === 'BODY' ? window : element;
86 this._config = this._getConfig(config);
87 this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS);
88 this._offsets = [];
89 this._targets = [];
90 this._activeTarget = null;
91 this._scrollHeight = 0;
92
93 $(this._scrollElement).on(Event.SCROLL, function (event) {
94 return _this._process(event);
95 });
96
97 this.refresh();
98 this._process();
99 }
100
101 // getters
102
103 // public
104
105 ScrollSpy.prototype.refresh = function refresh() {
106 var _this2 = this;
107
108 var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET;
109
110 var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
111
112 var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
113
114 this._offsets = [];
115 this._targets = [];
116
117 this._scrollHeight = this._getScrollHeight();
118
119 var targets = $.makeArray($(this._selector));
120
121 targets.map(function (element) {
122 var target = void 0;
123 var targetSelector = Util.getSelectorFromElement(element);
124
125 if (targetSelector) {
126 target = $(targetSelector)[0];
127 }
128
129 if (target && (target.offsetWidth || target.offsetHeight)) {
130 // todo (fat): remove sketch reliance on jQuery position/offset
131 return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
132 }
133 return null;
134 }).filter(function (item) {
135 return item;
136 }).sort(function (a, b) {
137 return a[0] - b[0];
138 }).forEach(function (item) {
139 _this2._offsets.push(item[0]);
140 _this2._targets.push(item[1]);
141 });
142 };
143
144 ScrollSpy.prototype.dispose = function dispose() {
145 $.removeData(this._element, DATA_KEY);
146 $(this._scrollElement).off(EVENT_KEY);
147
148 this._element = null;
149 this._scrollElement = null;
150 this._config = null;
151 this._selector = null;
152 this._offsets = null;
153 this._targets = null;
154 this._activeTarget = null;
155 this._scrollHeight = null;
156 };
157
158 // private
159
160 ScrollSpy.prototype._getConfig = function _getConfig(config) {
161 config = $.extend({}, Default, config);
162
163 if (typeof config.target !== 'string') {
164 var id = $(config.target).attr('id');
165 if (!id) {
166 id = Util.getUID(NAME);
167 $(config.target).attr('id', id);
168 }
169 config.target = '#' + id;
170 }
171
172 Util.typeCheckConfig(NAME, config, DefaultType);
173
174 return config;
175 };
176
177 ScrollSpy.prototype._getScrollTop = function _getScrollTop() {
178 return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
179 };
180
181 ScrollSpy.prototype._getScrollHeight = function _getScrollHeight() {
182 return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
183 };
184
185 ScrollSpy.prototype._getOffsetHeight = function _getOffsetHeight() {
186 return this._scrollElement === window ? window.innerHeight : this._scrollElement.offsetHeight;
187 };
188
189 ScrollSpy.prototype._process = function _process() {
190 var scrollTop = this._getScrollTop() + this._config.offset;
191 var scrollHeight = this._getScrollHeight();
192 var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
193
194 if (this._scrollHeight !== scrollHeight) {
195 this.refresh();
196 }
197
198 if (scrollTop >= maxScroll) {
199 var target = this._targets[this._targets.length - 1];
200
201 if (this._activeTarget !== target) {
202 this._activate(target);
203 }
204 return;
205 }
206
207 if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
208 this._activeTarget = null;
209 this._clear();
210 return;
211 }
212
213 for (var i = this._offsets.length; i--;) {
214 var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (this._offsets[i + 1] === undefined || scrollTop < this._offsets[i + 1]);
215
216 if (isActiveTarget) {
217 this._activate(this._targets[i]);
218 }
219 }
220 };
221
222 ScrollSpy.prototype._activate = function _activate(target) {
223 this._activeTarget = target;
224
225 this._clear();
226
227 var queries = this._selector.split(',');
228 queries = queries.map(function (selector) {
229 return selector + '[data-target="' + target + '"],' + (selector + '[href="' + target + '"]');
230 });
231
232 var $link = $(queries.join(','));
233
234 if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
235 $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
236 $link.addClass(ClassName.ACTIVE);
237 } else {
238 // todo (fat) this is kinda sus...
239 // recursively add actives to tested nav-links
240 $link.parents(Selector.LI).find('> ' + Selector.NAV_LINKS).addClass(ClassName.ACTIVE);
241 }
242
243 $(this._scrollElement).trigger(Event.ACTIVATE, {
244 relatedTarget: target
245 });
246 };
247
248 ScrollSpy.prototype._clear = function _clear() {
249 $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
250 };
251
252 // static
253
254 ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
255 return this.each(function () {
256 var data = $(this).data(DATA_KEY);
257 var _config = (typeof config === 'undefined' ? 'undefined' : _typeof(config)) === 'object' && config;
258
259 if (!data) {
260 data = new ScrollSpy(this, _config);
261 $(this).data(DATA_KEY, data);
262 }
263
264 if (typeof config === 'string') {
265 if (data[config] === undefined) {
266 throw new Error('No method named "' + config + '"');
267 }
268 data[config]();
269 }
270 });
271 };
272
273 _createClass(ScrollSpy, null, [{
274 key: 'VERSION',
275 get: function get() {
276 return VERSION;
277 }
278 }, {
279 key: 'Default',
280 get: function get() {
281 return Default;
282 }
283 }]);
284
285 return ScrollSpy;
286 }();
287
288 /**
289 * ------------------------------------------------------------------------
290 * Data Api implementation
291 * ------------------------------------------------------------------------
292 */
293
294 $(window).on(Event.LOAD_DATA_API, function () {
295 var scrollSpys = $.makeArray($(Selector.DATA_SPY));
296
297 for (var i = scrollSpys.length; i--;) {
298 var $spy = $(scrollSpys[i]);
299 ScrollSpy._jQueryInterface.call($spy, $spy.data());
300 }
301 });
302
303 /**
304 * ------------------------------------------------------------------------
305 * jQuery
306 * ------------------------------------------------------------------------
307 */
308
309 $.fn[NAME] = ScrollSpy._jQueryInterface;
310 $.fn[NAME].Constructor = ScrollSpy;
311 $.fn[NAME].noConflict = function () {
312 $.fn[NAME] = JQUERY_NO_CONFLICT;
313 return ScrollSpy._jQueryInterface;
314 };
315
316 return ScrollSpy;
317 }(jQuery);
318 //# sourceMappingURL=scrollspy.js.map