bootstrap 4.5.3 → 5.2.3

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.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +55 -0
  3. data/README.md +28 -5
  4. data/assets/javascripts/bootstrap/alert.js +54 -133
  5. data/assets/javascripts/bootstrap/base-component.js +99 -0
  6. data/assets/javascripts/bootstrap/button.js +44 -183
  7. data/assets/javascripts/bootstrap/carousel.js +308 -450
  8. data/assets/javascripts/bootstrap/collapse.js +180 -243
  9. data/assets/javascripts/bootstrap/dom/data.js +66 -0
  10. data/assets/javascripts/bootstrap/dom/event-handler.js +283 -0
  11. data/assets/javascripts/bootstrap/dom/manipulator.js +84 -0
  12. data/assets/javascripts/bootstrap/dom/selector-engine.js +85 -0
  13. data/assets/javascripts/bootstrap/dropdown.js +320 -387
  14. data/assets/javascripts/bootstrap/modal.js +238 -478
  15. data/assets/javascripts/bootstrap/offcanvas.js +297 -0
  16. data/assets/javascripts/bootstrap/popover.js +58 -163
  17. data/assets/javascripts/bootstrap/scrollspy.js +223 -228
  18. data/assets/javascripts/bootstrap/tab.js +251 -166
  19. data/assets/javascripts/bootstrap/toast.js +147 -149
  20. data/assets/javascripts/bootstrap/tooltip.js +434 -646
  21. data/assets/javascripts/bootstrap/util/backdrop.js +165 -0
  22. data/assets/javascripts/bootstrap/util/component-functions.js +46 -0
  23. data/assets/javascripts/bootstrap/util/config.js +79 -0
  24. data/assets/javascripts/bootstrap/util/focustrap.js +129 -0
  25. data/assets/javascripts/bootstrap/util/index.js +350 -0
  26. data/assets/javascripts/bootstrap/util/sanitizer.js +122 -0
  27. data/assets/javascripts/bootstrap/util/scrollbar.js +138 -0
  28. data/assets/javascripts/bootstrap/util/swipe.js +155 -0
  29. data/assets/javascripts/bootstrap/util/template-factory.js +177 -0
  30. data/assets/javascripts/bootstrap-global-this-define.js +6 -0
  31. data/assets/javascripts/bootstrap-global-this-undefine.js +2 -0
  32. data/assets/javascripts/bootstrap-sprockets.js +24 -8
  33. data/assets/javascripts/bootstrap.js +4037 -3206
  34. data/assets/javascripts/bootstrap.min.js +3 -3
  35. data/assets/stylesheets/_bootstrap-grid.scss +56 -21
  36. data/assets/stylesheets/_bootstrap-reboot.scss +4 -7
  37. data/assets/stylesheets/_bootstrap.scss +20 -13
  38. data/assets/stylesheets/bootstrap/_accordion.scss +149 -0
  39. data/assets/stylesheets/bootstrap/_alert.scss +33 -14
  40. data/assets/stylesheets/bootstrap/_badge.scss +15 -31
  41. data/assets/stylesheets/bootstrap/_breadcrumb.scss +23 -27
  42. data/assets/stylesheets/bootstrap/_button-group.scss +25 -46
  43. data/assets/stylesheets/bootstrap/_buttons.scss +136 -71
  44. data/assets/stylesheets/bootstrap/_card.scss +61 -113
  45. data/assets/stylesheets/bootstrap/_carousel.scss +64 -35
  46. data/assets/stylesheets/bootstrap/_close.scss +30 -30
  47. data/assets/stylesheets/bootstrap/_containers.scss +41 -0
  48. data/assets/stylesheets/bootstrap/_dropdown.scss +128 -71
  49. data/assets/stylesheets/bootstrap/_forms.scss +9 -347
  50. data/assets/stylesheets/bootstrap/_functions.scss +181 -23
  51. data/assets/stylesheets/bootstrap/_grid.scss +13 -53
  52. data/assets/stylesheets/bootstrap/_helpers.scss +10 -0
  53. data/assets/stylesheets/bootstrap/_images.scss +1 -1
  54. data/assets/stylesheets/bootstrap/_list-group.scss +72 -34
  55. data/assets/stylesheets/bootstrap/_maps.scss +54 -0
  56. data/assets/stylesheets/bootstrap/_mixins.scss +9 -13
  57. data/assets/stylesheets/bootstrap/_modal.scss +107 -110
  58. data/assets/stylesheets/bootstrap/_nav.scss +72 -23
  59. data/assets/stylesheets/bootstrap/_navbar.scss +127 -173
  60. data/assets/stylesheets/bootstrap/_offcanvas.scss +144 -0
  61. data/assets/stylesheets/bootstrap/_pagination.scss +72 -37
  62. data/assets/stylesheets/bootstrap/_placeholders.scss +51 -0
  63. data/assets/stylesheets/bootstrap/_popover.scss +99 -73
  64. data/assets/stylesheets/bootstrap/_progress.scss +26 -14
  65. data/assets/stylesheets/bootstrap/_reboot.scss +326 -200
  66. data/assets/stylesheets/bootstrap/_root.scss +62 -9
  67. data/assets/stylesheets/bootstrap/_spinners.scss +51 -22
  68. data/assets/stylesheets/bootstrap/_tables.scss +94 -115
  69. data/assets/stylesheets/bootstrap/_toasts.scss +54 -27
  70. data/assets/stylesheets/bootstrap/_tooltip.scss +68 -63
  71. data/assets/stylesheets/bootstrap/_transitions.scss +8 -1
  72. data/assets/stylesheets/bootstrap/_type.scss +40 -59
  73. data/assets/stylesheets/bootstrap/_utilities.scss +647 -18
  74. data/assets/stylesheets/bootstrap/_variables.scss +1018 -526
  75. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +18 -0
  76. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +75 -0
  77. data/assets/stylesheets/bootstrap/forms/_form-check.scss +175 -0
  78. data/assets/stylesheets/bootstrap/forms/_form-control.scss +194 -0
  79. data/assets/stylesheets/bootstrap/forms/_form-range.scss +91 -0
  80. data/assets/stylesheets/bootstrap/forms/_form-select.scss +71 -0
  81. data/assets/stylesheets/bootstrap/forms/_form-text.scss +11 -0
  82. data/assets/stylesheets/bootstrap/forms/_input-group.scss +132 -0
  83. data/assets/stylesheets/bootstrap/forms/_labels.scss +36 -0
  84. data/assets/stylesheets/bootstrap/forms/_validation.scss +12 -0
  85. data/assets/stylesheets/bootstrap/helpers/_color-bg.scss +10 -0
  86. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +12 -0
  87. data/assets/stylesheets/bootstrap/helpers/_position.scss +36 -0
  88. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +26 -0
  89. data/assets/stylesheets/bootstrap/helpers/_stacks.scss +15 -0
  90. data/assets/stylesheets/bootstrap/helpers/_stretched-link.scss +15 -0
  91. data/assets/stylesheets/bootstrap/helpers/_text-truncation.scss +7 -0
  92. data/assets/stylesheets/bootstrap/helpers/_visually-hidden.scss +8 -0
  93. data/assets/stylesheets/bootstrap/helpers/_vr.scss +8 -0
  94. data/assets/stylesheets/bootstrap/mixins/_alert.scss +8 -6
  95. data/assets/stylesheets/bootstrap/mixins/_backdrop.scss +14 -0
  96. data/assets/stylesheets/bootstrap/mixins/_banner.scss +9 -0
  97. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +10 -8
  98. data/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +7 -9
  99. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +20 -16
  100. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +60 -100
  101. data/assets/stylesheets/bootstrap/mixins/_caret.scss +10 -8
  102. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +2 -0
  103. data/assets/stylesheets/bootstrap/mixins/_color-scheme.scss +7 -0
  104. data/assets/stylesheets/bootstrap/mixins/_container.scss +11 -0
  105. data/assets/stylesheets/bootstrap/mixins/_forms.scss +48 -74
  106. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +13 -11
  107. data/assets/stylesheets/bootstrap/mixins/_grid.scss +119 -37
  108. data/assets/stylesheets/bootstrap/mixins/_image.scss +1 -21
  109. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +5 -2
  110. data/assets/stylesheets/bootstrap/mixins/_lists.scss +1 -1
  111. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +7 -19
  112. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +3 -3
  113. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +24 -0
  114. data/assets/stylesheets/bootstrap/mixins/_transition.scss +1 -1
  115. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +97 -0
  116. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +29 -0
  117. data/assets/stylesheets/bootstrap/utilities/_api.scss +47 -0
  118. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +278 -128
  119. data/bootstrap.gemspec +3 -5
  120. data/lib/bootstrap/version.rb +2 -2
  121. data/tasks/updater/js.rb +31 -7
  122. data/tasks/updater/network.rb +9 -3
  123. data/tasks/updater.rb +2 -2
  124. data/test/dummy_rails/app/assets/javascripts/application.js +4 -3
  125. data/test/dummy_rails/app/views/layouts/application.html.erb +3 -1
  126. data/test/dummy_rails/app/views/pages/root.html +89 -0
  127. data/test/dummy_rails/config/application.rb +0 -3
  128. data/test/gemfiles/rails_5_2.gemfile +8 -0
  129. data/test/gemfiles/rails_6_1.gemfile +7 -0
  130. data/test/gemfiles/rails_7_0.gemfile +7 -0
  131. data/test/test_helper.rb +3 -2
  132. metadata +70 -78
  133. data/.travis.yml +0 -31
  134. data/assets/javascripts/bootstrap/util.js +0 -192
  135. data/assets/stylesheets/bootstrap/_code.scss +0 -48
  136. data/assets/stylesheets/bootstrap/_custom-forms.scss +0 -524
  137. data/assets/stylesheets/bootstrap/_input-group.scss +0 -192
  138. data/assets/stylesheets/bootstrap/_jumbotron.scss +0 -17
  139. data/assets/stylesheets/bootstrap/_media.scss +0 -8
  140. data/assets/stylesheets/bootstrap/_print.scss +0 -141
  141. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -23
  142. data/assets/stylesheets/bootstrap/mixins/_badge.scss +0 -17
  143. data/assets/stylesheets/bootstrap/mixins/_float.scss +0 -14
  144. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -80
  145. data/assets/stylesheets/bootstrap/mixins/_hover.scss +0 -37
  146. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -11
  147. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +0 -34
  148. data/assets/stylesheets/bootstrap/mixins/_size.scss +0 -7
  149. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -39
  150. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -17
  151. data/assets/stylesheets/bootstrap/mixins/_text-hide.scss +0 -11
  152. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +0 -8
  153. data/assets/stylesheets/bootstrap/utilities/_align.scss +0 -8
  154. data/assets/stylesheets/bootstrap/utilities/_background.scss +0 -19
  155. data/assets/stylesheets/bootstrap/utilities/_borders.scss +0 -75
  156. data/assets/stylesheets/bootstrap/utilities/_display.scss +0 -26
  157. data/assets/stylesheets/bootstrap/utilities/_embed.scss +0 -39
  158. data/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -51
  159. data/assets/stylesheets/bootstrap/utilities/_float.scss +0 -11
  160. data/assets/stylesheets/bootstrap/utilities/_interactions.scss +0 -5
  161. data/assets/stylesheets/bootstrap/utilities/_overflow.scss +0 -5
  162. data/assets/stylesheets/bootstrap/utilities/_position.scss +0 -32
  163. data/assets/stylesheets/bootstrap/utilities/_screenreaders.scss +0 -11
  164. data/assets/stylesheets/bootstrap/utilities/_shadows.scss +0 -6
  165. data/assets/stylesheets/bootstrap/utilities/_sizing.scss +0 -20
  166. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +0 -73
  167. data/assets/stylesheets/bootstrap/utilities/_stretched-link.scss +0 -19
  168. data/assets/stylesheets/bootstrap/utilities/_text.scss +0 -72
  169. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +0 -13
  170. data/test/dummy_rails/app/views/pages/root.html.slim +0 -58
  171. /data/assets/stylesheets/bootstrap/{utilities → helpers}/_clearfix.scss +0 -0
@@ -1,316 +1,311 @@
1
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)
2
+ * Bootstrap scrollspy.js v5.2.3 (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('jquery'), require('./util.js')) :
8
- typeof define === 'function' && define.amd ? define(['jquery', './util.js'], factory) :
9
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ScrollSpy = factory(global.jQuery, global.Util));
10
- }(this, (function ($, Util) { 'use strict';
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
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
+ const _interopDefaultLegacy = e => e && typeof e === 'object' && 'default' in e ? e : { default: e };
13
13
 
14
- var $__default = /*#__PURE__*/_interopDefaultLegacy($);
15
- var Util__default = /*#__PURE__*/_interopDefaultLegacy(Util);
14
+ const EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
15
+ const SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
16
+ const BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
16
17
 
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); }
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); } }
20
-
21
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
22
18
  /**
23
- * ------------------------------------------------------------------------
19
+ * --------------------------------------------------------------------------
20
+ * Bootstrap (v5.2.3): scrollspy.js
21
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
22
+ * --------------------------------------------------------------------------
23
+ */
24
+ /**
24
25
  * Constants
25
- * ------------------------------------------------------------------------
26
26
  */
27
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: ''
28
+ const NAME = 'scrollspy';
29
+ const DATA_KEY = 'bs.scrollspy';
30
+ const EVENT_KEY = `.${DATA_KEY}`;
31
+ const DATA_API_KEY = '.data-api';
32
+ const EVENT_ACTIVATE = `activate${EVENT_KEY}`;
33
+ const EVENT_CLICK = `click${EVENT_KEY}`;
34
+ const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
35
+ const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
36
+ const CLASS_NAME_ACTIVE = 'active';
37
+ const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
38
+ const SELECTOR_TARGET_LINKS = '[href]';
39
+ const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
40
+ const SELECTOR_NAV_LINKS = '.nav-link';
41
+ const SELECTOR_NAV_ITEMS = '.nav-item';
42
+ const SELECTOR_LIST_ITEMS = '.list-group-item';
43
+ const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
44
+ const SELECTOR_DROPDOWN = '.dropdown';
45
+ const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
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]
38
53
  };
39
- var DefaultType = {
40
- offset: 'number',
41
- method: 'string',
42
- target: '(string|element)'
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'
43
61
  };
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
62
  /**
60
- * ------------------------------------------------------------------------
61
- * Class Definition
62
- * ------------------------------------------------------------------------
63
+ * Class definition
63
64
  */
64
65
 
65
- var ScrollSpy = /*#__PURE__*/function () {
66
- function ScrollSpy(element, config) {
67
- var _this = this;
66
+ class ScrollSpy extends BaseComponent__default.default {
67
+ constructor(element, config) {
68
+ super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper
68
69
 
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 = [];
70
+ this._targetLinks = new Map();
71
+ this._observableSections = new Map();
72
+ this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
75
73
  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();
74
+ this._observer = null;
75
+ this._previousScrollData = {
76
+ visibleEntryTop: 0,
77
+ parentScrollTop: 0
78
+ };
79
+ this.refresh(); // initialize
83
80
  } // Getters
84
81
 
85
82
 
86
- var _proto = ScrollSpy.prototype;
83
+ static get Default() {
84
+ return Default;
85
+ }
87
86
 
88
- // Public
89
- _proto.refresh = function refresh() {
90
- var _this2 = this;
87
+ static get DefaultType() {
88
+ return DefaultType;
89
+ }
91
90
 
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);
91
+ static get NAME() {
92
+ return NAME;
93
+ } // Public
102
94
 
103
- if (targetSelector) {
104
- target = document.querySelector(targetSelector);
105
- }
106
95
 
107
- if (target) {
108
- var targetBCR = target.getBoundingClientRect();
96
+ refresh() {
97
+ this._initializeTargetsAndObservables();
109
98
 
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
- }
99
+ this._maybeEnableSmoothScroll();
115
100
 
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]);
101
+ if (this._observer) {
102
+ this._observer.disconnect();
103
+ } else {
104
+ this._observer = this._getNewObserver();
105
+ }
123
106
 
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;
107
+ for (const section of this._observableSections.values()) {
108
+ this._observer.observe(section);
109
+ }
110
+ }
111
+
112
+ dispose() {
113
+ this._observer.disconnect();
114
+
115
+ super.dispose();
139
116
  } // Private
140
- ;
141
117
 
142
- _proto._getConfig = function _getConfig(config) {
143
- config = _extends({}, Default, typeof config === 'object' && config ? config : {});
144
118
 
145
- if (typeof config.target !== 'string' && Util__default['default'].isElement(config.target)) {
146
- var id = $__default['default'](config.target).attr('id');
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
147
122
 
148
- if (!id) {
149
- id = Util__default['default'].getUID(NAME);
150
- $__default['default'](config.target).attr('id', id);
151
- }
123
+ config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
152
124
 
153
- config.target = "#" + id;
125
+ if (typeof config.threshold === 'string') {
126
+ config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
154
127
  }
155
128
 
156
- Util__default['default'].typeCheckConfig(NAME, config, DefaultType);
157
129
  return config;
158
- };
130
+ }
159
131
 
160
- _proto._getScrollTop = function _getScrollTop() {
161
- return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
162
- };
132
+ _maybeEnableSmoothScroll() {
133
+ if (!this._config.smoothScroll) {
134
+ return;
135
+ } // unregister any previous listeners
163
136
 
164
- _proto._getScrollHeight = function _getScrollHeight() {
165
- return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
166
- };
167
137
 
168
- _proto._getOffsetHeight = function _getOffsetHeight() {
169
- return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
170
- };
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);
171
141
 
172
- _proto._process = function _process() {
173
- var scrollTop = this._getScrollTop() + this._config.offset;
142
+ if (observableSection) {
143
+ event.preventDefault();
144
+ const root = this._rootElement || window;
145
+ const height = observableSection.offsetTop - this._element.offsetTop;
174
146
 
175
- var scrollHeight = this._getScrollHeight();
147
+ if (root.scrollTo) {
148
+ root.scrollTo({
149
+ top: height,
150
+ behavior: 'smooth'
151
+ });
152
+ return;
153
+ } // Chrome 60 doesn't support `scrollTo`
176
154
 
177
- var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
178
155
 
179
- if (this._scrollHeight !== scrollHeight) {
180
- this.refresh();
181
- }
156
+ root.scrollTop = height;
157
+ }
158
+ });
159
+ }
160
+
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
169
+
170
+
171
+ _observerCallback(entries) {
172
+ const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
182
173
 
183
- if (scrollTop >= maxScroll) {
184
- var target = this._targets[this._targets.length - 1];
174
+ const activate = entry => {
175
+ this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
185
176
 
186
- if (this._activeTarget !== target) {
187
- this._activate(target);
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;
183
+
184
+ for (const entry of entries) {
185
+ if (!entry.isIntersecting) {
186
+ this._activeTarget = null;
187
+
188
+ this._clearActiveClass(targetElement(entry));
189
+
190
+ continue;
188
191
  }
189
192
 
190
- return;
191
- }
193
+ const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop
194
+
195
+ if (userScrollsDown && entryIsLowerThanPrevious) {
196
+ activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
192
197
 
193
- if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
194
- this._activeTarget = null;
198
+ if (!parentScrollTop) {
199
+ return;
200
+ }
195
201
 
196
- this._clear();
202
+ continue;
203
+ } // if we are scrolling up, pick the smallest offsetTop
197
204
 
198
- return;
205
+
206
+ if (!userScrollsDown && !entryIsLowerThanPrevious) {
207
+ activate(entry);
208
+ }
199
209
  }
210
+ }
211
+
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
+ }
222
+
223
+ const observableSection = SelectorEngine__default.default.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible
200
224
 
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]);
225
+ if (index.isVisible(observableSection)) {
226
+ this._targetLinks.set(anchor.hash, anchor);
203
227
 
204
- if (isActiveTarget) {
205
- this._activate(this._targets[i]);
228
+ this._observableSections.set(anchor.hash, observableSection);
206
229
  }
207
230
  }
208
- };
231
+ }
232
+
233
+ _process(target) {
234
+ if (this._activeTarget === target) {
235
+ return;
236
+ }
237
+
238
+ this._clearActiveClass(this._config.target);
209
239
 
210
- _proto._activate = function _activate(target) {
211
240
  this._activeTarget = target;
241
+ target.classList.add(CLASS_NAME_ACTIVE);
212
242
 
213
- this._clear();
243
+ this._activateParents(target);
214
244
 
215
- var queries = this._selector.split(',').map(function (selector) {
216
- return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
245
+ EventHandler__default.default.trigger(this._element, EVENT_ACTIVATE, {
246
+ relatedTarget: target
217
247
  });
248
+ }
218
249
 
219
- var $link = $__default['default']([].slice.call(document.querySelectorAll(queries.join(','))));
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
+ }
220
256
 
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
257
+ for (const listGroup of SelectorEngine__default.default.parents(target, SELECTOR_NAV_LIST_GROUP)) {
258
+ // Set triggered links parents as active
227
259
  // 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);
260
+ for (const item of SelectorEngine__default.default.prev(listGroup, SELECTOR_LINK_ITEMS)) {
261
+ item.classList.add(CLASS_NAME_ACTIVE);
262
+ }
232
263
  }
264
+ }
233
265
 
234
- $__default['default'](this._scrollElement).trigger(EVENT_ACTIVATE, {
235
- relatedTarget: target
236
- });
237
- };
266
+ _clearActiveClass(parent) {
267
+ parent.classList.remove(CLASS_NAME_ACTIVE);
268
+ const activeNodes = SelectorEngine__default.default.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE}`, parent);
238
269
 
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
- });
270
+ for (const node of activeNodes) {
271
+ node.classList.remove(CLASS_NAME_ACTIVE);
272
+ }
245
273
  } // Static
246
- ;
247
274
 
248
- ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
249
- return this.each(function () {
250
- var data = $__default['default'](this).data(DATA_KEY);
251
275
 
252
- var _config = typeof config === 'object' && config;
276
+ static jQueryInterface(config) {
277
+ return this.each(function () {
278
+ const data = ScrollSpy.getOrCreateInstance(this, config);
253
279
 
254
- if (!data) {
255
- data = new ScrollSpy(this, _config);
256
- $__default['default'](this).data(DATA_KEY, data);
280
+ if (typeof config !== 'string') {
281
+ return;
257
282
  }
258
283
 
259
- if (typeof config === 'string') {
260
- if (typeof data[config] === 'undefined') {
261
- throw new TypeError("No method named \"" + config + "\"");
262
- }
263
-
264
- data[config]();
284
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
285
+ throw new TypeError(`No method named "${config}"`);
265
286
  }
266
- });
267
- };
268
287
 
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
- }]);
288
+ data[config]();
289
+ });
290
+ }
280
291
 
281
- return ScrollSpy;
282
- }();
292
+ }
283
293
  /**
284
- * ------------------------------------------------------------------------
285
- * Data Api implementation
286
- * ------------------------------------------------------------------------
294
+ * Data API implementation
287
295
  */
288
296
 
289
297
 
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
+ EventHandler__default.default.on(window, EVENT_LOAD_DATA_API, () => {
299
+ for (const spy of SelectorEngine__default.default.find(SELECTOR_DATA_SPY)) {
300
+ ScrollSpy.getOrCreateInstance(spy);
298
301
  }
299
302
  });
300
303
  /**
301
- * ------------------------------------------------------------------------
302
304
  * jQuery
303
- * ------------------------------------------------------------------------
304
305
  */
305
306
 
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
- };
307
+ index.defineJQueryPlugin(ScrollSpy);
313
308
 
314
309
  return ScrollSpy;
315
310
 
316
- })));
311
+ }));