Passed
Pull Request — master (#45)
by
unknown
02:56
created

scrollspy.js ➔ _interopDefaultLegacy   B

Complexity

Conditions 7

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 1
dl 0
loc 1
rs 8
c 0
b 0
f 0
1
/*!
2
  * Bootstrap scrollspy.js v4.5.3 (https://getbootstrap.com/)
3
  * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
  */
6
(function (global, factory) {
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('./util.js')) :
8
  typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) :
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.jQuery, global.Util));
0 ignored issues
show
Bug introduced by
The variable globalThis seems to be never declared. If this is a global, consider adding a /** global: globalThis */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Best Practice introduced by
If you intend to check if the variable self is declared in the current environment, consider using typeof self === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
Comprehensibility introduced by
Usage of the sequence operator is discouraged, since it may lead to obfuscated code.

The sequence or comma operator allows the inclusion of multiple expressions where only is permitted. The result of the sequence is the value of the last expression.

This operator is most often used in for statements.

Used in another places it can make code hard to read, especially when people do not realize it even exists as a seperate operator.

This check looks for usage of the sequence operator in locations where it is not necessary and could be replaced by a series of expressions or statements.

var a,b,c;

a = 1, b = 1,  c= 3;

could just as well be written as:

var a,b,c;

a = 1;
b = 1;
c = 3;

To learn more about the sequence operator, please refer to the MDN.

Loading history...
10
}(this, (function ($, Util) { 'use strict';
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
14
  var $__default = /*#__PURE__*/_interopDefaultLegacy($);
15
  var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
16
17
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
0 ignored issues
show
Comprehensibility introduced by
It seems like you are trying to overwrite a function name here. _extends is already defined in line 17 as a function. While this will work, it can be very confusing.
Loading history...
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
18
19
  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); } }
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
20
21
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
22
  /**
23
   * ------------------------------------------------------------------------
24
   * Constants
25
   * ------------------------------------------------------------------------
26
   */
27
28
  var NAME = 'scrollspy';
29
  var VERSION = '4.5.3';
30
  var DATA_KEY = 'bs.scrollspy';
31
  var EVENT_KEY = "." + DATA_KEY;
32
  var DATA_API_KEY = '.data-api';
33
  var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME];
34
  var Default = {
35
    offset: 10,
36
    method: 'auto',
37
    target: ''
38
  };
39
  var DefaultType = {
40
    offset: 'number',
41
    method: 'string',
42
    target: '(string|element)'
43
  };
44
  var EVENT_ACTIVATE = "activate" + EVENT_KEY;
45
  var EVENT_SCROLL = "scroll" + EVENT_KEY;
46
  var EVENT_LOAD_DATA_API = "load" + EVENT_KEY + DATA_API_KEY;
47
  var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
48
  var CLASS_NAME_ACTIVE = 'active';
49
  var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
50
  var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
51
  var SELECTOR_NAV_LINKS = '.nav-link';
52
  var SELECTOR_NAV_ITEMS = '.nav-item';
53
  var SELECTOR_LIST_ITEMS = '.list-group-item';
54
  var SELECTOR_DROPDOWN = '.dropdown';
55
  var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
56
  var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
57
  var METHOD_OFFSET = 'offset';
58
  var METHOD_POSITION = 'position';
59
  /**
60
   * ------------------------------------------------------------------------
61
   * Class Definition
62
   * ------------------------------------------------------------------------
63
   */
64
65
  var ScrollSpy = /*#__PURE__*/function () {
66
    function ScrollSpy(element, config) {
67
      var _this = this;
68
69
      this._element = element;
70
      this._scrollElement = element.tagName === 'BODY' ? window : element;
71
      this._config = this._getConfig(config);
72
      this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
73
      this._offsets = [];
74
      this._targets = [];
75
      this._activeTarget = null;
76
      this._scrollHeight = 0;
77
      $__default['default'](this._scrollElement).on(EVENT_SCROLL, function (event) {
78
        return _this._process(event);
79
      });
80
      this.refresh();
81
82
      this._process();
83
    } // Getters
84
85
86
    var _proto = ScrollSpy.prototype;
87
88
    // Public
89
    _proto.refresh = function refresh() {
90
      var _this2 = this;
91
92
      var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
93
      var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
94
      var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
95
      this._offsets = [];
96
      this._targets = [];
97
      this._scrollHeight = this._getScrollHeight();
98
      var targets = [].slice.call(document.querySelectorAll(this._selector));
99
      targets.map(function (element) {
100
        var target;
101
        var targetSelector = Util__default['default'].getSelectorFromElement(element);
102
103
        if (targetSelector) {
104
          target = document.querySelector(targetSelector);
105
        }
106
107
        if (target) {
108
          var targetBCR = target.getBoundingClientRect();
109
110
          if (targetBCR.width || targetBCR.height) {
111
            // TODO (fat): remove sketch reliance on jQuery position/offset
112
            return [$__default['default'](target)[offsetMethod]().top + offsetBase, targetSelector];
113
          }
114
        }
115
116
        return null;
117
      }).filter(function (item) {
118
        return item;
119
      }).sort(function (a, b) {
120
        return a[0] - b[0];
121
      }).forEach(function (item) {
122
        _this2._offsets.push(item[0]);
123
124
        _this2._targets.push(item[1]);
125
      });
126
    };
127
128
    _proto.dispose = function dispose() {
129
      $__default['default'].removeData(this._element, DATA_KEY);
130
      $__default['default'](this._scrollElement).off(EVENT_KEY);
131
      this._element = null;
132
      this._scrollElement = null;
133
      this._config = null;
134
      this._selector = null;
135
      this._offsets = null;
136
      this._targets = null;
137
      this._activeTarget = null;
138
      this._scrollHeight = null;
139
    } // Private
140
    ;
141
142
    _proto._getConfig = function _getConfig(config) {
143
      config = _extends({}, Default, typeof config === 'object' && config ? config : {});
144
145
      if (typeof config.target !== 'string' && Util__default['default'].isElement(config.target)) {
146
        var id = $__default['default'](config.target).attr('id');
147
148
        if (!id) {
149
          id = Util__default['default'].getUID(NAME);
150
          $__default['default'](config.target).attr('id', id);
151
        }
152
153
        config.target = "#" + id;
154
      }
155
156
      Util__default['default'].typeCheckConfig(NAME, config, DefaultType);
157
      return config;
158
    };
159
160
    _proto._getScrollTop = function _getScrollTop() {
161
      return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
162
    };
163
164
    _proto._getScrollHeight = function _getScrollHeight() {
165
      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
166
    };
167
168
    _proto._getOffsetHeight = function _getOffsetHeight() {
169
      return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
170
    };
171
172
    _proto._process = function _process() {
173
      var scrollTop = this._getScrollTop() + this._config.offset;
174
175
      var scrollHeight = this._getScrollHeight();
176
177
      var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
178
179
      if (this._scrollHeight !== scrollHeight) {
180
        this.refresh();
181
      }
182
183
      if (scrollTop >= maxScroll) {
184
        var target = this._targets[this._targets.length - 1];
185
186
        if (this._activeTarget !== target) {
187
          this._activate(target);
188
        }
189
190
        return;
191
      }
192
193
      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
194
        this._activeTarget = null;
195
196
        this._clear();
197
198
        return;
199
      }
200
201
      for (var i = this._offsets.length; i--;) {
202
        var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
203
204
        if (isActiveTarget) {
205
          this._activate(this._targets[i]);
206
        }
207
      }
208
    };
209
210
    _proto._activate = function _activate(target) {
211
      this._activeTarget = target;
212
213
      this._clear();
214
215
      var queries = this._selector.split(',').map(function (selector) {
216
        return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
217
      });
218
219
      var $link = $__default['default']([].slice.call(document.querySelectorAll(queries.join(','))));
220
221
      if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
222
        $link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE);
223
        $link.addClass(CLASS_NAME_ACTIVE);
224
      } else {
225
        // Set triggered link as active
226
        $link.addClass(CLASS_NAME_ACTIVE); // Set triggered links parents as active
227
        // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
228
229
        $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_LINKS + ", " + SELECTOR_LIST_ITEMS).addClass(CLASS_NAME_ACTIVE); // Handle special case when .nav-link is inside .nav-item
230
231
        $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE);
232
      }
233
234
      $__default['default'](this._scrollElement).trigger(EVENT_ACTIVATE, {
235
        relatedTarget: target
236
      });
237
    };
238
239
    _proto._clear = function _clear() {
240
      [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
241
        return node.classList.contains(CLASS_NAME_ACTIVE);
242
      }).forEach(function (node) {
243
        return node.classList.remove(CLASS_NAME_ACTIVE);
244
      });
245
    } // Static
246
    ;
247
248 View Code Duplication
    ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
249
      return this.each(function () {
250
        var data = $__default['default'](this).data(DATA_KEY);
251
252
        var _config = typeof config === 'object' && config;
253
254
        if (!data) {
255
          data = new ScrollSpy(this, _config);
256
          $__default['default'](this).data(DATA_KEY, data);
257
        }
258
259
        if (typeof config === 'string') {
260
          if (typeof data[config] === 'undefined') {
261
            throw new TypeError("No method named \"" + config + "\"");
262
          }
263
264
          data[config]();
265
        }
266
      });
267
    };
268
269
    _createClass(ScrollSpy, null, [{
270
      key: "VERSION",
271
      get: function get() {
272
        return VERSION;
273
      }
274
    }, {
275
      key: "Default",
276
      get: function get() {
277
        return Default;
278
      }
279
    }]);
280
281
    return ScrollSpy;
282
  }();
283
  /**
284
   * ------------------------------------------------------------------------
285
   * Data Api implementation
286
   * ------------------------------------------------------------------------
287
   */
288
289
290
  $__default['default'](window).on(EVENT_LOAD_DATA_API, function () {
291
    var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
292
    var scrollSpysLength = scrollSpys.length;
293
294
    for (var i = scrollSpysLength; i--;) {
295
      var $spy = $__default['default'](scrollSpys[i]);
296
297
      ScrollSpy._jQueryInterface.call($spy, $spy.data());
298
    }
299
  });
300
  /**
301
   * ------------------------------------------------------------------------
302
   * jQuery
303
   * ------------------------------------------------------------------------
304
   */
305
306
  $__default['default'].fn[NAME] = ScrollSpy._jQueryInterface;
307
  $__default['default'].fn[NAME].Constructor = ScrollSpy;
308
309
  $__default['default'].fn[NAME].noConflict = function () {
310
    $__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
311
    return ScrollSpy._jQueryInterface;
312
  };
313
314
  return ScrollSpy;
315
316
})));
317
//# sourceMappingURL=scrollspy.js.map
318