bootstrap 4.6.0 → 5.3.2

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 (184) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +61 -0
  3. data/Gemfile +1 -0
  4. data/README.md +33 -6
  5. data/Rakefile +10 -1
  6. data/assets/javascripts/bootstrap/alert.js +53 -155
  7. data/assets/javascripts/bootstrap/base-component.js +83 -0
  8. data/assets/javascripts/bootstrap/button.js +43 -198
  9. data/assets/javascripts/bootstrap/carousel.js +285 -550
  10. data/assets/javascripts/bootstrap/collapse.js +169 -323
  11. data/assets/javascripts/bootstrap/dom/data.js +62 -0
  12. data/assets/javascripts/bootstrap/dom/event-handler.js +236 -0
  13. data/assets/javascripts/bootstrap/dom/manipulator.js +71 -0
  14. data/assets/javascripts/bootstrap/dom/selector-engine.js +103 -0
  15. data/assets/javascripts/bootstrap/dropdown.js +300 -467
  16. data/assets/javascripts/bootstrap/modal.js +226 -575
  17. data/assets/javascripts/bootstrap/offcanvas.js +245 -0
  18. data/assets/javascripts/bootstrap/popover.js +61 -205
  19. data/assets/javascripts/bootstrap/scrollspy.js +216 -287
  20. data/assets/javascripts/bootstrap/tab.js +226 -203
  21. data/assets/javascripts/bootstrap/toast.js +136 -209
  22. data/assets/javascripts/bootstrap/tooltip.js +411 -757
  23. data/assets/javascripts/bootstrap/util/backdrop.js +139 -0
  24. data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
  25. data/assets/javascripts/bootstrap/util/config.js +67 -0
  26. data/assets/javascripts/bootstrap/util/focustrap.js +113 -0
  27. data/assets/javascripts/bootstrap/util/index.js +281 -0
  28. data/assets/javascripts/bootstrap/util/sanitizer.js +110 -0
  29. data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
  30. data/assets/javascripts/bootstrap/util/swipe.js +134 -0
  31. data/assets/javascripts/bootstrap/util/template-factory.js +150 -0
  32. data/assets/javascripts/bootstrap-global-this-define.js +6 -0
  33. data/assets/javascripts/bootstrap-global-this-undefine.js +2 -0
  34. data/assets/javascripts/bootstrap-sprockets.js +23 -7
  35. data/assets/javascripts/bootstrap.js +3649 -3587
  36. data/assets/javascripts/bootstrap.min.js +3 -3
  37. data/assets/stylesheets/_bootstrap-grid.scss +53 -21
  38. data/assets/stylesheets/_bootstrap-reboot.scss +5 -7
  39. data/assets/stylesheets/_bootstrap-utilities.scss +19 -0
  40. data/assets/stylesheets/_bootstrap.scss +21 -13
  41. data/assets/stylesheets/bootstrap/_accordion.scss +158 -0
  42. data/assets/stylesheets/bootstrap/_alert.scss +32 -16
  43. data/assets/stylesheets/bootstrap/_badge.scss +15 -31
  44. data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -24
  45. data/assets/stylesheets/bootstrap/_button-group.scss +27 -48
  46. data/assets/stylesheets/bootstrap/_buttons.scss +136 -71
  47. data/assets/stylesheets/bootstrap/_card.scss +66 -113
  48. data/assets/stylesheets/bootstrap/_carousel.scss +83 -36
  49. data/assets/stylesheets/bootstrap/_close.scss +51 -28
  50. data/assets/stylesheets/bootstrap/_containers.scss +41 -0
  51. data/assets/stylesheets/bootstrap/_dropdown.scss +129 -71
  52. data/assets/stylesheets/bootstrap/_forms.scss +9 -347
  53. data/assets/stylesheets/bootstrap/_functions.scss +181 -23
  54. data/assets/stylesheets/bootstrap/_grid.scss +18 -52
  55. data/assets/stylesheets/bootstrap/_helpers.scss +12 -0
  56. data/assets/stylesheets/bootstrap/_images.scss +1 -1
  57. data/assets/stylesheets/bootstrap/_list-group.scss +77 -34
  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 +107 -110
  61. data/assets/stylesheets/bootstrap/_nav.scss +102 -25
  62. data/assets/stylesheets/bootstrap/_navbar.scss +129 -172
  63. data/assets/stylesheets/bootstrap/_offcanvas.scss +146 -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 +44 -24
  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 +8 -1
  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 +87 -0
  78. data/assets/stylesheets/bootstrap/_variables.scss +1216 -615
  79. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +95 -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 +53 -85
  112. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +13 -11
  113. data/assets/stylesheets/bootstrap/mixins/_grid.scss +119 -37
  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 +3 -3
  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 +276 -132
  125. data/bootstrap.gemspec +6 -7
  126. data/lib/bootstrap/engine.rb +7 -1
  127. data/lib/bootstrap/version.rb +2 -2
  128. data/tasks/updater/js.rb +31 -7
  129. data/tasks/updater/network.rb +9 -3
  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 -3
  136. data/test/gemfiles/rails_4_2.gemfile +1 -1
  137. data/test/gemfiles/rails_5_0.gemfile +1 -1
  138. data/test/gemfiles/rails_5_1.gemfile +1 -1
  139. data/test/gemfiles/rails_5_2.gemfile +8 -0
  140. data/test/gemfiles/rails_6_0.gemfile +1 -0
  141. data/test/gemfiles/rails_6_1.gemfile +8 -0
  142. data/test/gemfiles/rails_7_0_dartsass.gemfile +8 -0
  143. data/test/gemfiles/rails_7_0_sassc.gemfile +8 -0
  144. data/test/test_helper.rb +3 -2
  145. metadata +97 -85
  146. data/.travis.yml +0 -31
  147. data/assets/javascripts/bootstrap/util.js +0 -192
  148. data/assets/stylesheets/bootstrap/_code.scss +0 -48
  149. data/assets/stylesheets/bootstrap/_custom-forms.scss +0 -526
  150. data/assets/stylesheets/bootstrap/_input-group.scss +0 -208
  151. data/assets/stylesheets/bootstrap/_jumbotron.scss +0 -17
  152. data/assets/stylesheets/bootstrap/_media.scss +0 -8
  153. data/assets/stylesheets/bootstrap/_print.scss +0 -141
  154. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -23
  155. data/assets/stylesheets/bootstrap/mixins/_badge.scss +0 -17
  156. data/assets/stylesheets/bootstrap/mixins/_float.scss +0 -14
  157. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -80
  158. data/assets/stylesheets/bootstrap/mixins/_hover.scss +0 -37
  159. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -11
  160. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +0 -34
  161. data/assets/stylesheets/bootstrap/mixins/_size.scss +0 -7
  162. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -39
  163. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -17
  164. data/assets/stylesheets/bootstrap/mixins/_text-hide.scss +0 -11
  165. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +0 -8
  166. data/assets/stylesheets/bootstrap/utilities/_align.scss +0 -8
  167. data/assets/stylesheets/bootstrap/utilities/_background.scss +0 -19
  168. data/assets/stylesheets/bootstrap/utilities/_borders.scss +0 -75
  169. data/assets/stylesheets/bootstrap/utilities/_display.scss +0 -26
  170. data/assets/stylesheets/bootstrap/utilities/_embed.scss +0 -39
  171. data/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -51
  172. data/assets/stylesheets/bootstrap/utilities/_float.scss +0 -11
  173. data/assets/stylesheets/bootstrap/utilities/_interactions.scss +0 -5
  174. data/assets/stylesheets/bootstrap/utilities/_overflow.scss +0 -5
  175. data/assets/stylesheets/bootstrap/utilities/_position.scss +0 -32
  176. data/assets/stylesheets/bootstrap/utilities/_screenreaders.scss +0 -11
  177. data/assets/stylesheets/bootstrap/utilities/_shadows.scss +0 -6
  178. data/assets/stylesheets/bootstrap/utilities/_sizing.scss +0 -20
  179. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +0 -73
  180. data/assets/stylesheets/bootstrap/utilities/_stretched-link.scss +0 -19
  181. data/assets/stylesheets/bootstrap/utilities/_text.scss +0 -72
  182. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +0 -13
  183. data/test/dummy_rails/app/views/pages/root.html.slim +0 -58
  184. /data/assets/stylesheets/bootstrap/{utilities → helpers}/_clearfix.scss +0 -0
@@ -1,345 +1,274 @@
1
1
  /*!
2
- * Bootstrap scrollspy.js v4.6.0 (https://getbootstrap.com/)
3
- * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
2
+ * Bootstrap scrollspy.js v5.3.2 (https://getbootstrap.com/)
3
+ * Copyright 2011-2023 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
- return Constructor;
31
- }
32
-
33
- function _extends() {
34
- _extends = Object.assign || function (target) {
35
- for (var i = 1; i < arguments.length; i++) {
36
- var source = arguments[i];
37
-
38
- for (var key in source) {
39
- if (Object.prototype.hasOwnProperty.call(source, key)) {
40
- target[key] = source[key];
41
- }
42
- }
43
- }
12
+ /**
13
+ * --------------------------------------------------------------------------
14
+ * Bootstrap scrollspy.js
15
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16
+ * --------------------------------------------------------------------------
17
+ */
44
18
 
45
- return target;
46
- };
47
-
48
- return _extends.apply(this, arguments);
49
- }
50
19
 
51
20
  /**
52
- * ------------------------------------------------------------------------
53
21
  * Constants
54
- * ------------------------------------------------------------------------
55
22
  */
56
23
 
57
- var NAME = 'scrollspy';
58
- var VERSION = '4.6.0';
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 Default = {
64
- offset: 10,
65
- method: 'auto',
66
- 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]
67
49
  };
68
- var DefaultType = {
69
- offset: 'number',
70
- method: 'string',
71
- 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'
72
57
  };
73
- var EVENT_ACTIVATE = "activate" + EVENT_KEY;
74
- var EVENT_SCROLL = "scroll" + EVENT_KEY;
75
- var EVENT_LOAD_DATA_API = "load" + EVENT_KEY + DATA_API_KEY;
76
- var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
77
- var CLASS_NAME_ACTIVE = 'active';
78
- var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
79
- var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
80
- var SELECTOR_NAV_LINKS = '.nav-link';
81
- var SELECTOR_NAV_ITEMS = '.nav-item';
82
- var SELECTOR_LIST_ITEMS = '.list-group-item';
83
- var SELECTOR_DROPDOWN = '.dropdown';
84
- var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
85
- var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
86
- var METHOD_OFFSET = 'offset';
87
- var METHOD_POSITION = 'position';
58
+
88
59
  /**
89
- * ------------------------------------------------------------------------
90
- * Class Definition
91
- * ------------------------------------------------------------------------
60
+ * Class definition
92
61
  */
93
62
 
94
- var ScrollSpy = /*#__PURE__*/function () {
95
- function ScrollSpy(element, config) {
96
- var _this = this;
63
+ class ScrollSpy extends BaseComponent {
64
+ constructor(element, config) {
65
+ super(element, config);
97
66
 
98
- this._element = element;
99
- this._scrollElement = element.tagName === 'BODY' ? window : element;
100
- this._config = this._getConfig(config);
101
- this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
102
- this._offsets = [];
103
- 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;
104
71
  this._activeTarget = null;
105
- this._scrollHeight = 0;
106
- $__default['default'](this._scrollElement).on(EVENT_SCROLL, function (event) {
107
- return _this._process(event);
108
- });
109
- this.refresh();
110
-
111
- this._process();
112
- } // Getters
113
-
72
+ this._observer = null;
73
+ this._previousScrollData = {
74
+ visibleEntryTop: 0,
75
+ parentScrollTop: 0
76
+ };
77
+ this.refresh(); // initialize
78
+ }
114
79
 
115
- 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
+ }
116
90
 
117
91
  // Public
118
- _proto.refresh = function refresh() {
119
- var _this2 = this;
120
-
121
- var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
122
- var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
123
- var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
124
- this._offsets = [];
125
- this._targets = [];
126
- this._scrollHeight = this._getScrollHeight();
127
- var targets = [].slice.call(document.querySelectorAll(this._selector));
128
- targets.map(function (element) {
129
- var target;
130
- 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
+ }
131
108
 
132
- if (targetSelector) {
133
- target = document.querySelector(targetSelector);
134
- }
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;
135
113
 
136
- if (target) {
137
- 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
+ }
138
125
 
139
- if (targetBCR.width || targetBCR.height) {
140
- // TODO (fat): remove sketch reliance on jQuery position/offset
141
- 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;
142
140
  }
143
- }
144
141
 
145
- return null;
146
- }).filter(function (item) {
147
- return item;
148
- }).sort(function (a, b) {
149
- return a[0] - b[0];
150
- }).forEach(function (item) {
151
- _this2._offsets.push(item[0]);
152
-
153
- _this2._targets.push(item[1]);
142
+ // Chrome 60 doesn't support `scrollTo`
143
+ root.scrollTop = height;
144
+ }
154
145
  });
155
- };
156
-
157
- _proto.dispose = function dispose() {
158
- $__default['default'].removeData(this._element, DATA_KEY);
159
- $__default['default'](this._scrollElement).off(EVENT_KEY);
160
- this._element = null;
161
- this._scrollElement = null;
162
- this._config = null;
163
- this._selector = null;
164
- this._offsets = null;
165
- this._targets = null;
166
- this._activeTarget = null;
167
- this._scrollHeight = null;
168
- } // Private
169
- ;
170
-
171
- _proto._getConfig = function _getConfig(config) {
172
- config = _extends({}, Default, typeof config === 'object' && config ? config : {});
173
-
174
- if (typeof config.target !== 'string' && Util__default['default'].isElement(config.target)) {
175
- 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
+ }
176
155
 
177
- if (!id) {
178
- id = Util__default['default'].getUID(NAME);
179
- $__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;
180
181
  }
181
182
 
182
- config.target = "#" + id;
183
- }
184
-
185
- Util__default['default'].typeCheckConfig(NAME, config, DefaultType);
186
- return config;
187
- };
188
-
189
- _proto._getScrollTop = function _getScrollTop() {
190
- return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
191
- };
192
-
193
- _proto._getScrollHeight = function _getScrollHeight() {
194
- return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
195
- };
196
-
197
- _proto._getOffsetHeight = function _getOffsetHeight() {
198
- return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
199
- };
200
-
201
- _proto._process = function _process() {
202
- var scrollTop = this._getScrollTop() + this._config.offset;
203
-
204
- var scrollHeight = this._getScrollHeight();
205
-
206
- var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
207
-
208
- if (this._scrollHeight !== scrollHeight) {
209
- this.refresh();
183
+ // if we are scrolling up, pick the smallest offsetTop
184
+ if (!userScrollsDown && !entryIsLowerThanPrevious) {
185
+ activate(entry);
186
+ }
210
187
  }
211
-
212
- if (scrollTop >= maxScroll) {
213
- var target = this._targets[this._targets.length - 1];
214
-
215
- if (this._activeTarget !== target) {
216
- 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;
217
197
  }
198
+ const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);
218
199
 
219
- 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
+ }
220
205
  }
221
-
222
- if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
223
- this._activeTarget = null;
224
-
225
- this._clear();
226
-
206
+ }
207
+ _process(target) {
208
+ if (this._activeTarget === target) {
227
209
  return;
228
210
  }
229
-
230
- for (var i = this._offsets.length; i--;) {
231
- var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
232
-
233
- if (isActiveTarget) {
234
- this._activate(this._targets[i]);
235
- }
236
- }
237
- };
238
-
239
- _proto._activate = function _activate(target) {
211
+ this._clearActiveClass(this._config.target);
240
212
  this._activeTarget = target;
241
-
242
- this._clear();
243
-
244
- var queries = this._selector.split(',').map(function (selector) {
245
- 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
246
217
  });
247
-
248
- var $link = $__default['default']([].slice.call(document.querySelectorAll(queries.join(','))));
249
-
250
- if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
251
- $link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE);
252
- $link.addClass(CLASS_NAME_ACTIVE);
253
- } else {
254
- // Set triggered link as active
255
- $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
256
227
  // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
257
-
258
- $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
259
-
260
- $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
+ }
261
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
+ }
262
240
 
263
- $__default['default'](this._scrollElement).trigger(EVENT_ACTIVATE, {
264
- relatedTarget: target
265
- });
266
- };
267
-
268
- _proto._clear = function _clear() {
269
- [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
270
- return node.classList.contains(CLASS_NAME_ACTIVE);
271
- }).forEach(function (node) {
272
- return node.classList.remove(CLASS_NAME_ACTIVE);
273
- });
274
- } // Static
275
- ;
276
-
277
- ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
241
+ // Static
242
+ static jQueryInterface(config) {
278
243
  return this.each(function () {
279
- var data = $__default['default'](this).data(DATA_KEY);
280
-
281
- var _config = typeof config === 'object' && config;
282
-
283
- if (!data) {
284
- data = new ScrollSpy(this, _config);
285
- $__default['default'](this).data(DATA_KEY, data);
244
+ const data = ScrollSpy.getOrCreateInstance(this, config);
245
+ if (typeof config !== 'string') {
246
+ return;
286
247
  }
287
-
288
- if (typeof config === 'string') {
289
- if (typeof data[config] === 'undefined') {
290
- throw new TypeError("No method named \"" + config + "\"");
291
- }
292
-
293
- data[config]();
248
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
249
+ throw new TypeError(`No method named "${config}"`);
294
250
  }
251
+ data[config]();
295
252
  });
296
- };
297
-
298
- _createClass(ScrollSpy, null, [{
299
- key: "VERSION",
300
- get: function get() {
301
- return VERSION;
302
- }
303
- }, {
304
- key: "Default",
305
- get: function get() {
306
- return Default;
307
- }
308
- }]);
253
+ }
254
+ }
309
255
 
310
- return ScrollSpy;
311
- }();
312
256
  /**
313
- * ------------------------------------------------------------------------
314
- * Data Api implementation
315
- * ------------------------------------------------------------------------
257
+ * Data API implementation
316
258
  */
317
259
 
318
-
319
- $__default['default'](window).on(EVENT_LOAD_DATA_API, function () {
320
- var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
321
- var scrollSpysLength = scrollSpys.length;
322
-
323
- for (var i = scrollSpysLength; i--;) {
324
- var $spy = $__default['default'](scrollSpys[i]);
325
-
326
- 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);
327
263
  }
328
264
  });
265
+
329
266
  /**
330
- * ------------------------------------------------------------------------
331
267
  * jQuery
332
- * ------------------------------------------------------------------------
333
268
  */
334
269
 
335
- $__default['default'].fn[NAME] = ScrollSpy._jQueryInterface;
336
- $__default['default'].fn[NAME].Constructor = ScrollSpy;
337
-
338
- $__default['default'].fn[NAME].noConflict = function () {
339
- $__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
340
- return ScrollSpy._jQueryInterface;
341
- };
270
+ index_js.defineJQueryPlugin(ScrollSpy);
342
271
 
343
272
  return ScrollSpy;
344
273
 
345
- })));
274
+ }));