bootstrap 4.6.2.1 → 5.3.5

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