bootstrap 4.6.2 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) 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 +50 -147
  5. data/assets/javascripts/bootstrap/base-component.js +83 -0
  6. data/assets/javascripts/bootstrap/button.js +40 -190
  7. data/assets/javascripts/bootstrap/carousel.js +282 -537
  8. data/assets/javascripts/bootstrap/collapse.js +166 -314
  9. data/assets/javascripts/bootstrap/dom/data.js +62 -0
  10. data/assets/javascripts/bootstrap/dom/event-handler.js +236 -0
  11. data/assets/javascripts/bootstrap/dom/manipulator.js +71 -0
  12. data/assets/javascripts/bootstrap/dom/selector-engine.js +103 -0
  13. data/assets/javascripts/bootstrap/dropdown.js +297 -455
  14. data/assets/javascripts/bootstrap/modal.js +223 -566
  15. data/assets/javascripts/bootstrap/offcanvas.js +245 -0
  16. data/assets/javascripts/bootstrap/popover.js +59 -208
  17. data/assets/javascripts/bootstrap/scrollspy.js +213 -276
  18. data/assets/javascripts/bootstrap/tab.js +222 -200
  19. data/assets/javascripts/bootstrap/toast.js +137 -206
  20. data/assets/javascripts/bootstrap/tooltip.js +403 -746
  21. data/assets/javascripts/bootstrap/util/backdrop.js +139 -0
  22. data/assets/javascripts/bootstrap/util/component-functions.js +41 -0
  23. data/assets/javascripts/bootstrap/util/config.js +67 -0
  24. data/assets/javascripts/bootstrap/util/focustrap.js +113 -0
  25. data/assets/javascripts/bootstrap/util/index.js +281 -0
  26. data/assets/javascripts/bootstrap/util/sanitizer.js +110 -0
  27. data/assets/javascripts/bootstrap/util/scrollbar.js +112 -0
  28. data/assets/javascripts/bootstrap/util/swipe.js +134 -0
  29. data/assets/javascripts/bootstrap/util/template-factory.js +150 -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 +21 -5
  33. data/assets/javascripts/bootstrap.js +3623 -3485
  34. data/assets/javascripts/bootstrap.min.js +3 -3
  35. data/assets/stylesheets/_bootstrap-grid.scss +53 -21
  36. data/assets/stylesheets/_bootstrap-reboot.scss +5 -7
  37. data/assets/stylesheets/_bootstrap.scss +21 -13
  38. data/assets/stylesheets/bootstrap/_accordion.scss +158 -0
  39. data/assets/stylesheets/bootstrap/_alert.scss +32 -16
  40. data/assets/stylesheets/bootstrap/_badge.scss +15 -31
  41. data/assets/stylesheets/bootstrap/_breadcrumb.scss +22 -24
  42. data/assets/stylesheets/bootstrap/_button-group.scss +27 -48
  43. data/assets/stylesheets/bootstrap/_buttons.scss +136 -71
  44. data/assets/stylesheets/bootstrap/_card.scss +66 -113
  45. data/assets/stylesheets/bootstrap/_carousel.scss +78 -34
  46. data/assets/stylesheets/bootstrap/_close.scss +51 -28
  47. data/assets/stylesheets/bootstrap/_containers.scss +41 -0
  48. data/assets/stylesheets/bootstrap/_dropdown.scss +129 -71
  49. data/assets/stylesheets/bootstrap/_forms.scss +9 -347
  50. data/assets/stylesheets/bootstrap/_functions.scss +135 -23
  51. data/assets/stylesheets/bootstrap/_grid.scss +18 -52
  52. data/assets/stylesheets/bootstrap/_helpers.scss +12 -0
  53. data/assets/stylesheets/bootstrap/_list-group.scss +77 -34
  54. data/assets/stylesheets/bootstrap/_maps.scss +174 -0
  55. data/assets/stylesheets/bootstrap/_mixins.scss +10 -15
  56. data/assets/stylesheets/bootstrap/_modal.scss +107 -110
  57. data/assets/stylesheets/bootstrap/_nav.scss +99 -27
  58. data/assets/stylesheets/bootstrap/_navbar.scss +129 -172
  59. data/assets/stylesheets/bootstrap/_offcanvas.scss +146 -0
  60. data/assets/stylesheets/bootstrap/_pagination.scss +72 -37
  61. data/assets/stylesheets/bootstrap/_placeholders.scss +51 -0
  62. data/assets/stylesheets/bootstrap/_popover.scss +99 -73
  63. data/assets/stylesheets/bootstrap/_progress.scss +35 -14
  64. data/assets/stylesheets/bootstrap/_reboot.scss +318 -192
  65. data/assets/stylesheets/bootstrap/_root.scss +174 -9
  66. data/assets/stylesheets/bootstrap/_spinners.scss +43 -23
  67. data/assets/stylesheets/bootstrap/_tables.scss +101 -115
  68. data/assets/stylesheets/bootstrap/_toasts.scss +54 -27
  69. data/assets/stylesheets/bootstrap/_tooltip.scss +67 -63
  70. data/assets/stylesheets/bootstrap/_transitions.scss +3 -2
  71. data/assets/stylesheets/bootstrap/_type.scss +40 -59
  72. data/assets/stylesheets/bootstrap/_utilities.scss +806 -18
  73. data/assets/stylesheets/bootstrap/_variables-dark.scss +85 -0
  74. data/assets/stylesheets/bootstrap/_variables.scss +1202 -606
  75. data/assets/stylesheets/bootstrap/bootstrap-utilities.scss +19 -0
  76. data/assets/stylesheets/bootstrap/forms/_floating-labels.scss +95 -0
  77. data/assets/stylesheets/bootstrap/forms/_form-check.scss +188 -0
  78. data/assets/stylesheets/bootstrap/forms/_form-control.scss +214 -0
  79. data/assets/stylesheets/bootstrap/forms/_form-range.scss +91 -0
  80. data/assets/stylesheets/bootstrap/forms/_form-select.scss +80 -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 +7 -0
  86. data/assets/stylesheets/bootstrap/helpers/_colored-links.scss +30 -0
  87. data/assets/stylesheets/bootstrap/helpers/_focus-ring.scss +5 -0
  88. data/assets/stylesheets/bootstrap/helpers/_icon-link.scss +25 -0
  89. data/assets/stylesheets/bootstrap/helpers/_position.scss +36 -0
  90. data/assets/stylesheets/bootstrap/helpers/_ratio.scss +26 -0
  91. data/assets/stylesheets/bootstrap/helpers/_stacks.scss +15 -0
  92. data/assets/stylesheets/bootstrap/helpers/_stretched-link.scss +15 -0
  93. data/assets/stylesheets/bootstrap/helpers/_text-truncation.scss +7 -0
  94. data/assets/stylesheets/bootstrap/helpers/_visually-hidden.scss +8 -0
  95. data/assets/stylesheets/bootstrap/helpers/_vr.scss +8 -0
  96. data/assets/stylesheets/bootstrap/mixins/_alert.scss +11 -6
  97. data/assets/stylesheets/bootstrap/mixins/_backdrop.scss +14 -0
  98. data/assets/stylesheets/bootstrap/mixins/_banner.scss +7 -0
  99. data/assets/stylesheets/bootstrap/mixins/_border-radius.scss +10 -8
  100. data/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +7 -9
  101. data/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +20 -16
  102. data/assets/stylesheets/bootstrap/mixins/_buttons.scss +60 -100
  103. data/assets/stylesheets/bootstrap/mixins/_caret.scss +34 -27
  104. data/assets/stylesheets/bootstrap/mixins/_clearfix.scss +2 -0
  105. data/assets/stylesheets/bootstrap/mixins/_color-mode.scss +21 -0
  106. data/assets/stylesheets/bootstrap/mixins/_color-scheme.scss +7 -0
  107. data/assets/stylesheets/bootstrap/mixins/_container.scss +11 -0
  108. data/assets/stylesheets/bootstrap/mixins/_forms.scss +54 -96
  109. data/assets/stylesheets/bootstrap/mixins/_gradients.scss +13 -11
  110. data/assets/stylesheets/bootstrap/mixins/_grid.scss +118 -36
  111. data/assets/stylesheets/bootstrap/mixins/_image.scss +1 -21
  112. data/assets/stylesheets/bootstrap/mixins/_list-group.scss +7 -2
  113. data/assets/stylesheets/bootstrap/mixins/_lists.scss +1 -1
  114. data/assets/stylesheets/bootstrap/mixins/_pagination.scss +7 -19
  115. data/assets/stylesheets/bootstrap/mixins/_reset-text.scss +2 -2
  116. data/assets/stylesheets/bootstrap/mixins/_table-variants.scss +24 -0
  117. data/assets/stylesheets/bootstrap/mixins/_transition.scss +1 -1
  118. data/assets/stylesheets/bootstrap/mixins/_utilities.scss +97 -0
  119. data/assets/stylesheets/bootstrap/mixins/_visually-hidden.scss +33 -0
  120. data/assets/stylesheets/bootstrap/utilities/_api.scss +47 -0
  121. data/assets/stylesheets/bootstrap/vendor/_rfs.scss +211 -91
  122. data/bootstrap.gemspec +3 -5
  123. data/lib/bootstrap/version.rb +2 -2
  124. data/tasks/updater/js.rb +17 -5
  125. data/tasks/updater/network.rb +2 -2
  126. data/tasks/updater/scss.rb +1 -1
  127. data/tasks/updater.rb +2 -2
  128. data/test/dummy_rails/app/assets/javascripts/application.js +4 -3
  129. data/test/dummy_rails/app/views/layouts/application.html.erb +3 -1
  130. data/test/dummy_rails/app/views/pages/root.html +89 -0
  131. data/test/dummy_rails/config/application.rb +0 -3
  132. data/test/gemfiles/rails_5_2.gemfile +8 -0
  133. data/test/gemfiles/rails_6_1.gemfile +7 -0
  134. data/test/gemfiles/rails_7_0.gemfile +7 -0
  135. data/test/test_helper.rb +3 -2
  136. metadata +78 -82
  137. data/.travis.yml +0 -31
  138. data/assets/javascripts/bootstrap/util.js +0 -189
  139. data/assets/stylesheets/bootstrap/_code.scss +0 -48
  140. data/assets/stylesheets/bootstrap/_custom-forms.scss +0 -526
  141. data/assets/stylesheets/bootstrap/_input-group.scss +0 -211
  142. data/assets/stylesheets/bootstrap/_jumbotron.scss +0 -17
  143. data/assets/stylesheets/bootstrap/_media.scss +0 -8
  144. data/assets/stylesheets/bootstrap/_print.scss +0 -132
  145. data/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -23
  146. data/assets/stylesheets/bootstrap/mixins/_badge.scss +0 -17
  147. data/assets/stylesheets/bootstrap/mixins/_float.scss +0 -14
  148. data/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -80
  149. data/assets/stylesheets/bootstrap/mixins/_hover.scss +0 -37
  150. data/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -11
  151. data/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +0 -34
  152. data/assets/stylesheets/bootstrap/mixins/_size.scss +0 -7
  153. data/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -39
  154. data/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -17
  155. data/assets/stylesheets/bootstrap/mixins/_text-hide.scss +0 -11
  156. data/assets/stylesheets/bootstrap/mixins/_visibility.scss +0 -8
  157. data/assets/stylesheets/bootstrap/utilities/_align.scss +0 -8
  158. data/assets/stylesheets/bootstrap/utilities/_background.scss +0 -19
  159. data/assets/stylesheets/bootstrap/utilities/_borders.scss +0 -75
  160. data/assets/stylesheets/bootstrap/utilities/_display.scss +0 -26
  161. data/assets/stylesheets/bootstrap/utilities/_embed.scss +0 -39
  162. data/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -51
  163. data/assets/stylesheets/bootstrap/utilities/_float.scss +0 -11
  164. data/assets/stylesheets/bootstrap/utilities/_interactions.scss +0 -5
  165. data/assets/stylesheets/bootstrap/utilities/_overflow.scss +0 -5
  166. data/assets/stylesheets/bootstrap/utilities/_position.scss +0 -32
  167. data/assets/stylesheets/bootstrap/utilities/_screenreaders.scss +0 -11
  168. data/assets/stylesheets/bootstrap/utilities/_shadows.scss +0 -6
  169. data/assets/stylesheets/bootstrap/utilities/_sizing.scss +0 -20
  170. data/assets/stylesheets/bootstrap/utilities/_spacing.scss +0 -73
  171. data/assets/stylesheets/bootstrap/utilities/_stretched-link.scss +0 -19
  172. data/assets/stylesheets/bootstrap/utilities/_text.scss +0 -72
  173. data/assets/stylesheets/bootstrap/utilities/_visibility.scss +0 -13
  174. data/test/dummy_rails/app/views/pages/root.html.slim +0 -58
  175. /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.1 (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
- 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